10.07.2015 Views

Is Parallel Programming Hard, And, If So, What Can You Do About It?

Is Parallel Programming Hard, And, If So, What Can You Do About It?

Is Parallel Programming Hard, And, If So, What Can You Do About It?

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

F.7. CHAPTER 8: DEFERRED PROCESSING 301when bar() advances to line 14, it will attempt toacquire my_lock, which is held by foo().Each function is then waiting for a lock that theother holds, a classic deadlock.Other RCU implementations neither spin norblock in rcu_read_lock(), hence avoiding deadlocks.Quick Quiz 8.35:Why not simply use reader-writer locks in the RCUimplementation in Figure 8.27 in order to allowRCU readers to proceed in parallel?Answer:One could in fact use reader-writer locks in thismanner. However, textbook reader-writer lockssuffer from memory contention, so that the RCUread-side critical sections would need to be quitelong to actually permit parallel execution [McK03].Ontheotherhand, useofareader-writerlockthatis read-acquired in rcu_read_lock() would avoidthe deadlock condition noted above.Quick Quiz 8.36:Wouldn’t it be cleaner to acquire all the locks, andthen release them all in the loop from lines 15-18of Figure 8.28? After all, with this change, therewould be a point in time when there were noreaders, simplifying things greatly.Answer:Making this change would re-introduce the deadlock,so no, it would not be cleaner.Quick Quiz 8.37:<strong>Is</strong> the implementation shown in Figure 8.28 freefrom deadlocks? Why or why not?Answer:One deadlock is where a lock is held acrosssynchronize_rcu(), and that same lock is acquiredwithin an RCU read-side critical section.However, this situation will deadlock any correctlydesigned RCU implementation. After all, thesynchronize_rcu() primitive must wait for allpre-existing RCU read-side critical sections tocomplete, but if one of those critical sections isspinning on a lock held by the thread executing thesynchronize_rcu(), we have a deadlock inherentin the definition of RCU.Another deadlock happens when attempting tonest RCU read-side critical sections. This deadlockispeculiartothisimplementation,andmightbeavoided by using recursive locks, or by using readerwriterlocks that are read-acquired by rcu_read_lock() and write-acquired by synchronize_rcu().However, if we exclude the above two cases, thisimplementation of RCU does not introduce anydeadlock situations. This is because only time someother thread’s lock is acquired is when executingsynchronize_rcu(), and in that case, the lock isimmediately released, prohibiting a deadlock cyclethat does not involve a lock held across thesynchronize_rcu() which is the first case above.Quick Quiz 8.38:<strong>Is</strong>n’t one advantage of the RCU algorithm shownin Figure 8.28 that it uses only primitives that arewidely available, for example, in POSIX pthreads?Answer:This is indeed an advantage, but do not forget thatrcu_dereference() and rcu_assign_pointer()are still required, which means volatile manipulationfor rcu_dereference() and memory barriersfor rcu_assign_pointer(). Of course, many AlphaCPUs require memory barriers for both primitives.Quick Quiz 8.39:But what if you hold a lock across a call tosynchronize_rcu(), and then acquire that samelock within an RCU read-side critical section?Answer:Indeed, this would deadlock any legal RCU implementation.But is rcu_read_lock() reallyparticipating in the deadlock cycle? <strong>If</strong> you believethat it is, then please ask yourself this same questionwhen looking at the RCU implementation inSection 8.3.4.9.Quick Quiz 8.40:How can the grace period possibly elapse in 40nanoseconds when synchronize_rcu() contains a10-millisecond delay?Answer:The update-side test was run in absence of readers,so the poll() system call was never invoked. Inaddition, the actual code has this poll() systemcall commented out, the better to evaluate the true

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!