Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does guarding a variable with a pthread mutex guarantee it's also not cached?

Tags:

c

pthreads

Consider a simple (global in my case) variable:

int i; 

Somewhere this variable is accessed

pthread_mutex_lock(i_mutex); if(i == other value) {   do_something(); } pthread_mutex_unlock(i_mutex); 

Another thread updates i while it holds i_mutex . Could the compiler cache the value of i so I don't get the recent value ? Must i be volatile ?

like image 358
Anonym Avatar asked Jul 08 '10 21:07

Anonym


People also ask

Is pthread mutex lock blocking?

Yes, it is a blocking call and will block until it gets the lock.

What happens when mutex is locked?

Mutexes are used to protect shared resources. If the mutex is already locked by another thread, the thread waits for the mutex to become available. The thread that has locked a mutex becomes its current owner and remains the owner until the same thread has unlocked it.

Is pthread mutex lock a cancellation point?

pthread_mutex_lock() is not a cancellation point, although it may block indefinitely; making pthread_mutex_lock() a cancellation point would make writing correct cancellation handlers difficult, if not impossible.

Does pthread_cond_wait unlock mutex?

The pthread_cond_wait() function atomically unlocks mutex and performs the wait for the condition. In this case, atomically means with respect to the mutex and the condition variable and another threads access to those objects through the pthread condition variable interfaces.


2 Answers

pthread locks implement memory barriers that will ensure that cache effects are made visible to other threads. You don't need volatile to properly deal with the shared variable i if the accesses to the shared variable are protected by pthread mutexes.

from http://www.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_11:

The following functions synchronize memory with respect to other threads:

fork() pthread_barrier_wait() pthread_cond_broadcast() pthread_cond_signal() pthread_cond_timedwait() pthread_cond_wait() pthread_create() pthread_join() pthread_mutex_lock()       // <==== pthread_mutex_timedlock() pthread_mutex_trylock() pthread_mutex_unlock()     // <==== pthread_spin_lock() pthread_spin_trylock() pthread_spin_unlock() pthread_rwlock_rdlock() pthread_rwlock_timedrdlock() pthread_rwlock_timedwrlock() pthread_rwlock_tryrdlock() pthread_rwlock_trywrlock() pthread_rwlock_unlock() pthread_rwlock_wrlock() sem_post() sem_timedwait() sem_trywait() sem_wait() semctl() semop() wait() waitpid() 
like image 144
Michael Burr Avatar answered Sep 21 '22 11:09

Michael Burr


A compiler should not cache such a global value across a function call.

But I think your question is ill-posed. First, POSIX mutex only work when you stick to their semantics. So you have to apply some discipline in your code to only access global variables (i in that case) whence your mutex is hold.

Second, please don't think that volatile declarations would prevent you from any damage that such a non-respect of the access rules would cause. Concurrent read and write into memory is a subtle subject.

like image 31
Jens Gustedt Avatar answered Sep 22 '22 11:09

Jens Gustedt