Sophie

Sophie

distrib > CentOS > 6 > i386 > by-pkgid > 2c51d8eb79f8810ada971ee8c30ce1e5 > files > 2210

kernel-doc-2.6.32-71.14.1.el6.noarch.rpm

<?xml version="1.0" encoding="ANSI_X3.4-1968" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=ANSI_X3.4-1968" /><title>Protecting The Objects Themselves</title><meta name="generator" content="DocBook XSL Stylesheets V1.75.2" /><link rel="home" href="index.html" title="Unreliable Guide To Locking" /><link rel="up" href="ch07.html" title="Chapter&#160;7.&#160;Common Examples" /><link rel="prev" href="ch07s03.html" title="Exposing Objects Outside This File" /><link rel="next" href="ch08.html" title="Chapter&#160;8.&#160;Common Problems" /></head><body><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Protecting The Objects Themselves</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ch07s03.html">Prev</a>&#160;</td><th width="60%" align="center">Chapter&#160;7.&#160;Common Examples</th><td width="20%" align="right">&#160;<a accesskey="n" href="ch08.html">Next</a></td></tr></table><hr /></div><div class="sect1" title="Protecting The Objects Themselves"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="examples-lock-per-obj"></a>Protecting The Objects Themselves</h2></div></div></div><p>
In these examples, we assumed that the objects (except the reference
counts) never changed once they are created.  If we wanted to allow
the name to change, there are three possibilities:
    </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>
You can make <span class="symbol">cache_lock</span> non-static, and tell people
to grab that lock before changing the name in any object.
        </p></li><li class="listitem"><p>
You can provide a <code class="function">cache_obj_rename</code> which grabs
this lock and changes the name for the caller, and tell everyone to
use that function.
        </p></li><li class="listitem"><p>
You can make the <span class="symbol">cache_lock</span> protect only the cache
itself, and use another lock to protect the name.
        </p></li></ul></div><p>
Theoretically, you can make the locks as fine-grained as one lock for
every field, for every object.  In practice, the most common variants
are:
</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>
One lock which protects the infrastructure (the <span class="symbol">cache</span>
list in this example) and all the objects.  This is what we have done
so far.
	</p></li><li class="listitem"><p>
One lock which protects the infrastructure (including the list
pointers inside the objects), and one lock inside the object which
protects the rest of that object.
        </p></li><li class="listitem"><p>
Multiple locks to protect the infrastructure (eg. one lock per hash
chain), possibly with a separate per-object lock.
        </p></li></ul></div><p>
Here is the "lock-per-object" implementation:
</p><pre class="programlisting">
--- cache.c.refcnt-atomic	2003-12-11 15:50:54.000000000 +1100
+++ cache.c.perobjectlock	2003-12-11 17:15:03.000000000 +1100
@@ -6,11 +6,17 @@

 struct object
 {
+        /* These two protected by cache_lock. */
         struct list_head list;
+        int popularity;
+
         atomic_t refcnt;
+
+        /* Doesn't change once created. */
         int id;
+
+        spinlock_t lock; /* Protects the name */
         char name[32];
-        int popularity;
 };

 static DEFINE_SPINLOCK(cache_lock);
@@ -77,6 +84,7 @@
         obj-&gt;id = id;
         obj-&gt;popularity = 0;
         atomic_set(&amp;obj-&gt;refcnt, 1); /* The cache holds a reference */
+        spin_lock_init(&amp;obj-&gt;lock);

         spin_lock_irqsave(&amp;cache_lock, flags);
         __cache_add(obj);
</pre><p>
Note that I decide that the <em class="structfield"><code>popularity</code></em>
count should be protected by the <span class="symbol">cache_lock</span> rather
than the per-object lock: this is because it (like the
<span class="structname">struct list_head</span> inside the object) is
logically part of the infrastructure.  This way, I don't need to grab
the lock of every object in <code class="function">__cache_add</code> when
seeking the least popular.
</p><p>
I also decided that the <em class="structfield"><code>id</code></em> member is
unchangeable, so I don't need to grab each object lock in
<code class="function">__cache_find()</code> to examine the
<em class="structfield"><code>id</code></em>: the object lock is only used by a
caller who wants to read or write the <em class="structfield"><code>name</code></em>
field.
</p><p>
Note also that I added a comment describing what data was protected by
which locks.  This is extremely important, as it describes the runtime
behavior of the code, and can be hard to gain from just reading.  And
as Alan Cox says, <span class="quote">&#8220;<span class="quote">Lock data, not code</span>&#8221;</span>.
</p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ch07s03.html">Prev</a>&#160;</td><td width="20%" align="center"><a accesskey="u" href="ch07.html">Up</a></td><td width="40%" align="right">&#160;<a accesskey="n" href="ch08.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Exposing Objects Outside This File&#160;</td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top">&#160;Chapter&#160;8.&#160;Common Problems</td></tr></table></div></body></html>