Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
Read-copy-update
(section)
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
==Simple implementation== RCU has extremely simple "toy" implementations that can aid understanding of RCU. This section presents one such "toy" implementation that works in a [[Cooperative multitasking|non-preemptive environment]].<ref>{{Cite conference | last1 = McKenney | first1 = Paul E. | last2 = Appavoo | first2 = Jonathan | last3 = Kleen | first3 = Andi | last4 = Krieger | first4 = Orran | last5 = Russell | first5 = Rusty | last6 = Sarma | first6 = Dipankar | last7 = Soni | first7 = Maneesh | title = Read-Copy Update | url = http://www.rdrop.com/users/paulmck/RCU/rclock_OLS.2001.05.01c.pdf | journal = Ottawa Linux Symposium | date = July 2001 }}</ref> <syntaxhighlight lang="c"> void rcu_read_lock(void) { } void rcu_read_unlock(void) { } void call_rcu(void (*callback) (void *), void *arg) { // add callback/arg pair to a list } void synchronize_rcu(void) { int cpu, ncpus = 0; for each_cpu(cpu) schedule_current_task_to(cpu); for each entry in the call_rcu list entry->callback (entry->arg); } </syntaxhighlight> In the code sample, <code>rcu_assign_pointer</code> and <code>rcu_dereference</code> can be ignored without missing much. However, they are needed in order to suppress harmful compiler optimization and to prevent CPUs from reordering accesses. <syntaxhighlight lang="c"> #define rcu_assign_pointer(p, v) ({ \ smp_wmb(); /* Order previous writes. */ \ ACCESS_ONCE(p) = (v); \ }) #define rcu_dereference(p) ({ \ typeof(p) _value = ACCESS_ONCE(p); \ smp_read_barrier_depends(); /* nop on most architectures */ \ (_value); \ }) </syntaxhighlight> Note that <code>rcu_read_lock</code> and <code>rcu_read_unlock</code> do nothing. This is the great strength of classic RCU in a non-preemptive kernel: read-side overhead is precisely zero, as <code>smp_read_barrier_depends()</code> is an empty macro on all but [[DEC Alpha]] CPUs;<ref>{{cite web | last = Wizard | first = The | title = Shared Memory, Threads, Interprocess Communication | publisher = [[Hewlett-Packard]] | date = August 2001 | url = http://www.openvms.compaq.com/wizard/wiz_2637.html | access-date = December 26, 2010 }}</ref>{{failed verification|reason=The source does not discuss the Linux smp_read_barrier_depends operation, and certainly doesn't comment on any other type of CPU.|date=November 2015}} such memory barriers are not needed on modern CPUs. The <code>ACCESS_ONCE()</code> macro is a volatile cast that generates no additional code in most cases. And there is no way that <code>rcu_read_lock</code> can participate in a [[deadlock (computer science)|deadlock]] cycle, cause a realtime process to miss its scheduling deadline, precipitate [[priority inversion]], or result in high [[lock (computer science)|lock contention]]. However, in this toy RCU implementation, blocking within an RCU read-side critical section is illegal, just as is blocking while holding a pure spinlock. The implementation of <code>synchronize_rcu</code> moves the caller of synchronize_cpu to each CPU, thus blocking until all CPUs have been able to perform the context switch. Recall that this is a non-preemptive environment and that blocking within an RCU read-side critical section is illegal, which imply that there can be no preemption points within an RCU read-side critical section. Therefore, if a given CPU executes a context switch (to schedule another process), we know that this CPU must have completed all preceding RCU read-side critical sections. Once all CPUs have executed a context switch, then all preceding RCU read-side critical sections will have completed.
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)