Hi All,
I have some further understanding about the code. If thread A can go back to its home cpu(core 1), this means it is not running on the core 2. And when A release its lock, it will switch to its helper. During the context switch from thread A to its helper on core 2, the " _running_under_lock" of thread A should be set to false. Thus thread A is able to continue to run on its home cpu.
I think this logic has no problem. But I observed a thread going into the infinite loop in Switch_lock::set_lock_owner method. in my test program. Because of inappropriate memory barrier, or anything else?
Thank you very much. Best, Yuxin
On Wed, Aug 27, 2014 at 2:28 PM, Yuxin Ren ryx@gwmail.gwu.edu wrote:
Hi All,
I have a question about the dec_lock_cnt method in Context class under multiple processor. In its implementation, it checks if thread's home cpu is equal to current cpu. If not, it does not unset "_running_under_lock" variable, even if the _lock_cnt is 0. Why does it check if home cpu is equal to current cpu?
Consider the following case: Thread A is running on core 1 holding a helping lock, but is preempted by another high priority thread. Thread B is running on core 2, and tries to take the same helping lock. It finds the lock is held by A, so it helps A to run by migrating A to core 2. When A releases its lock, finding the current cpu is not its home cpu, so it does not set "_running_under_lock" to false. Then A continues to run on core 1 and tries to take that lock again. But now it can never take the lock, as the implementation of helping lock.
PRIVATE inline bool NO_INSTRUMENT Switch_lock::set_lock_owner(Context *o) { bool have_no_locks = o->_lock_cnt < 1;
if (have_no_locks) { assert_kdb (current_cpu() == o->home_cpu()); for (;;) { if (EXPECT_FALSE(access_once(&o->_running_under_lock))) continue; if (EXPECT_TRUE(mp_cas(&o->_running_under_lock, Mword(false), Mword(true)))) break; } } ... }
Do I misunderstand anything here?
Thank you very much. Best, Yuxin