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.

78 CHAPTER 8. DEFERRED PROCESSINGfirstnext next nextprev prev prevA B CFigure 8.9: Linux Linear Linked List1 struct foo {2 struct hlist_node *list;3 int a;4 int b;5 int c;6 };7 HLIST_HEAD(head);89 /* . . . */1011 p = kmalloc(sizeof(*p), GFP_KERNEL);12 p->a = 1;13 p->b = 2;14 p->c = 3;15 hlist_add_head_rcu(&p->list, &head);Figure 8.10: RCU hlist PublicationAdapting the pointer-publish example for thelinked list results in the code shown in Figure 8.8.Line 15 must be protected by some synchronizationmechanism (most commonly some sort of lock)to prevent multiple list_add() instances from executingconcurrently. However, such synchronizationdoes not prevent this list_add() instance from executingconcurrently with RCU readers.Subscribing to an RCU-protected list is straightforward:1 rcu_read_lock();2 list_for_each_entry_rcu(p, head, list) {3 do_something_with(p->a, p->b, p->c);4 }5 rcu_read_unlock();Thelist_add_rcu()primitivepublishesanentryinto the specified list, guaranteeing that the correspondinglist_for_each_entry_rcu() invocationwill properly subscribe to this same entry.Quick Quiz 8.7: <strong>What</strong> prevents thelist for each entry rcu() from getting a segfaultif it happens to execute at exactly the same time asthe list add rcu()?Linux’s other doubly linked list, the hlist, is a linearlist, which means that it needs only one pointerfor the header rather than the two required for thecircularlist, asshowninFigure8.9. Thus, useofhlistcan halve the memory consumption for the hashbucketarrays of large hash tables. As before, thisnotationiscumbersome, sohlistswillbeabbreviatedin the same way lists are, as shown in Figure 8.7.Publishing a new element to an RCU-protectedhlist is quite similar to doing so for the circular list,as shown in Figure 8.10.As before, line 15 must be protected by some sortof synchronization mechanism, for example, a lock.Subscribing to an RCU-protected hlist is also similarto the circular list:1 rcu_read_lock();2 hlist_for_each_entry_rcu(p, q, head, list) {3 do_something_with(p->a, p->b, p->c);4 }5 rcu_read_unlock();Quick Quiz 8.8: Why do we need to pass twopointers into hlist for each entry rcu() whenonly one is needed for list for each entry rcu()?The set of RCU publish and subscribe primitivesare shown in Table 8.2, along with additional primitivesto “unpublish”, or retract.Note that the list_replace_rcu(), list_del_rcu(), hlist_replace_rcu(), and hlist_del_rcu() AP<strong>Is</strong> add a complication. When is it safeto free up the data element that was replaced or removed?In particular, how can we possibly knowwhen all the readers have released their referencesto that data element?Thesequestionsareaddressedinthefollowingsection.8.3.1.2 Wait For Pre-Existing RCU Readersto CompleteIn its most basic form, RCU is a way of waiting forthings to finish. Of course, there are a great manyother ways of waiting for things to finish, includingreference counts, reader-writer locks, events, and soon. The great advantage of RCU is that it can waitfor each of (say) 20,000 different things without havingto explicitly track each and every one of them,and without having to worry about the performancedegradation, scalability limitations, complex deadlockscenarios, and memory-leak hazards that areinherent in schemes using explicit tracking.In RCU’s case, the things waited on are called“RCU read-side critical sections”. An RCU readsidecritical section starts with an rcu_read_lock()primitive, and ends with a correspondingrcu_read_unlock() primitive. RCU read-side critical sectionscan be nested, and may contain pretty muchany code, as long as that code does not explicitlyblock or sleep (although a special form of RCUcalled SRCU [McK06] does permit general sleepingin SRCU read-side critical sections). <strong>If</strong> you abide bythese conventions, you can use RCU to wait for anydesired piece of code to complete.

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

Saved successfully!

Ooh no, something went wrong!