<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Chris Pitchin&#039; Hey</title>
	<atom:link href="http://blog.mozilla.com/cjones/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.mozilla.com/cjones</link>
	<description>Mozilla hacks and suchlike</description>
	<lastBuildDate>Wed, 25 Nov 2009 19:28:29 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Helping ld link libxul more quickly</title>
		<link>http://blog.mozilla.com/cjones/2009/11/25/helping-ld-link-libxul-more-quickly/</link>
		<comments>http://blog.mozilla.com/cjones/2009/11/25/helping-ld-link-libxul-more-quickly/#comments</comments>
		<pubDate>Wed, 25 Nov 2009 19:28:29 +0000</pubDate>
		<dc:creator>cjones</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.mozilla.com/cjones/?p=45</guid>
		<description><![CDATA[I used to do most of my development in a Linux virtual machine with 1.5GB of RAM.  There, &#8211;enable-libxul builds were &#8230; painful: linking libxul itself took about 2 minutes and 30 seconds.  Ideally, ld or gold would know how to re-link incrementally, and the problem would vanish.  But until then, you [...]]]></description>
			<content:encoded><![CDATA[<p>I used to do most of my development in a Linux virtual machine with 1.5GB of RAM.  There, &#8211;enable-libxul builds were &#8230; painful: linking libxul itself took about 2 minutes and 30 seconds.  Ideally, ld or gold would know how to re-link incrementally, and the problem would vanish.  But until then, you can help ld out by adding a flag in your mozconfig</p>
<pre>
...
export LDFLAGS="-Wl,--no-keep-memory"
</pre>
<p>This tells ld to optimize for memory usage rather than speed.  On my 1.5GB VM, this made a big difference because it kept ld from hitting swap as much; the link time went from ~2:30 to ~1:30.  Also see https://bugzilla.mozilla.org/show_bug.cgi?id=494068.</p>
<p>CAVEAT EMPTOR: if you have a machine with &#8220;lots of RAM&#8221;, this flag might actually <strong>hurt</strong> link times.  Also, it&#8217;s worth pointing out that the best way to speed up libxul link times is to add more RAM to your build machine, if possible.  (My bright shiny new build machine can link libxul in about 5 seconds, so I don&#8217;t use &#8211;no-keep-memory anymore.)</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.com/cjones/2009/11/25/helping-ld-link-libxul-more-quickly/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Introducing porky.py: Low-fat pork</title>
		<link>http://blog.mozilla.com/cjones/2009/08/04/introducing-porky-py-low-fat-pork/</link>
		<comments>http://blog.mozilla.com/cjones/2009/08/04/introducing-porky-py-low-fat-pork/#comments</comments>
		<pubDate>Tue, 04 Aug 2009 21:16:09 +0000</pubDate>
		<dc:creator>cjones</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.mozilla.com/cjones/?p=23</guid>
		<description><![CDATA[Porky.py (pronounced &#8220;porky pie&#8221;) is a simple C++ rewriting tool built on top of pork.  Porky.py aims to make pork usable for a larger class of code rewriting problems by lowering pork&#8217;s high learning curve and making it easier to code up rewrite passes.
If you want to skip the exposition and play with the [...]]]></description>
			<content:encoded><![CDATA[<p>Porky.py (pronounced &#8220;porky pie&#8221;) is a simple C++ rewriting tool built on top of <a href="https://developer.mozilla.org/en/Pork">pork</a>.  Porky.py aims to make pork usable for a larger class of code rewriting problems by lowering pork&#8217;s high learning curve and making it easier to code up rewrite passes.</p>
<p>If you want to skip the exposition and play with the code, it&#8217;s available <a href="http://hg.mozilla.org/rewriting-and-analysis/pork/">here</a>.  Just follow the <a href="https://developer.mozilla.org/en/Installing_Pork">pork install instructions</a> to get started.</p>
<h4>Background</h4>
<p>Porky.py started back in April when I wanted to <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=486606">rewrite a bunch of code</a>.  I was (well, am still, sigh) replacing a C API with a new C++ API.  Basically, code that looked like this</p>
<pre>
PRLock* lock = PR_NewLock();
PR_Lock(lock);
PR_Unlock(lock);
PR_DestroyLock(lock);
</pre>
<p>was going to be changed into this</p>
<pre>
Mutex* lock = new Mutex();
lock->Lock();
lock->Unlock();
delete lock;
</pre>
<p>I quickly estimated that these old APIs were used in O(1000) places in our code, which was way more than I wanted to edit by hand.  (I&#8217;m <a href="http://www.c2.com/cgi/wiki?LazinessImpatienceHubris">lazy</a>, so sue me.)  So I wanted an automated tool.  However, this rewrite task is just beyond the reach of regular-expression-based tools like sed; existing code could do something like <code>PR_Lock(GetStruct().GetPRLock())</code>, which causes sed to barf.  Of course there&#8217;s the pork tool, which can eat this kind of rewrite for breakfast, but looking at existing pork tools convinced me that, for this relatively simple rewrite, it was going to be a waste of work to (i) learn pork&#8217;s AST classes; (ii) learn its AST visitor idioms; (iii) learn the non-standard utility libraries pork depends on (sm::string, FakeList, &#8230;); (iv) learn pork&#8217;s patch generation library; (v) code the tool in C++ &#8230; sigh.</p>
<p>So I was stuck with either doing a half-assed rewrite with sed and spending a few days fixing up its mistakes, or wasting a week or so coding a pork tool.  Half-assed rewrites suck.  But in the <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=486606">bug report</a> I filed, I realized that I was naturally describing the rewrite in a way that an automated tool could understand.  I have some background in programming languages, so in the spirit of Terence Parr</p>
<blockquote><p>
&#8220;Why program by hand in five days what you can spend five <strike>years</strike>days of your life automating?&#8221;
</p></blockquote>
<p>I decided to write my own tool on top of pork.</p>
<h4>Porky.py&#8217;s specification language</h4>
<p>Porky.py&#8217;s domain-specific language (DSL) for rewrites was designed with this use case in mind</p>
<ul>
<li>a C++ developer not familiar with porky.py wants to do something like my API rewrite example above</li>
<li>doesn&#8217;t want to spend several days learning pork</li>
<li>and doesn&#8217;t want to learn an obscure DSL</li>
<li>(it&#8217;d be nice if the tool were fast, too)</li>
</ul>
<p>So these requirements to me implied that, first, the porky.py DSL should be &#8220;minimal&#8221; in the sense of minimal additional syntax beyond C++&#8217;s &#8212; less to learn.  And second, porky.py should target expression-level rewrites (as API changes usually are) rather than statement level.  Statement-level rewrites complicate things.</p>
<p>Below is a working porky.py solution to the rewrite problem posed above.  You can decide for yourself whether it meets my criteria.</p>
<pre>
rewrite SyncPrimitiveUpgrade {
  type PRLock* => Mutex*
  call PR_NewLock() => new Mutex()
  call PR_Lock(lock) => lock->Lock()
  call PR_Unlock(lock) => lock->Unlock()
  call PR_DestroyLock(lock) => delete lock
}
</pre>
<p>The rewrite rule <code>type PRLock* => Mutex*</code> means: everywhere the type &#8220;PRLock*&#8221; appears, change it into &#8220;Mutex*&#8221;.  The second kind of rule here, <code>PR_Lock(lock) => lock->Lock()</code> is more interesting; it means that, at any callsite matching</p>
<pre>PR_Lock($lock$)</pre>
<p>where <code>$lock$</code> is any expression, change this line into</p>
<pre>$lock$->Lock()</pre>
<p>These kinds of rules are porky.py&#8217;s big advantage over sed et al.: because pork.py has access to a C++ AST through pork, it can match patterns that require strictly more power than regular expressions provide.  One can write rules like <code>call Foo(a, b, c) => c.Method(b, a)</code>, and the rule will rewrite call sites like <code>Foo(x().y().z(), r(s(t)), u.v.w())</code> into <code>u.v.w().Method(r(s(t)), x().y().z())</code>.</p>
<p>And finally, porky.py provides the creature comfort of one-liner shell invocations for really simple rewrites</p>
<pre>porkyc -e 'call SomeFun(a, b) => OtherFun(b, a)'</pre>
<p>After which the compiled pork tool can be invoked.  (Docs forthcoming on MDC.)</p>
<h4>Code rewriting workflow when using porky.py</h4>
<p>After writing porky.py, I used it to edit a large quantity of code in a couple of hours.  These patches haven&#8217;t all made it into mozilla-central yet (for a variety of reasons), but I wanted to show the steps I took to generate them.  This will eventually find its way into an MDC guide.</p>
<pre>
$ porkyc -m sync_primitive_upgrade.porky
  (outputs and compiles code in |SyncPrimitiveUpgrade.code/|)
$ SyncPrimitiveUpgrade.code/dorewrite ~/mozilla-code/*.ii -x *nspr* > mozilla-code.patch
   (does n-way parallel rewrite on matching files; n depends on your system)
   (doesn't include files matching the pattern *nspr* in the patch)
   (writes patch to stdout)
</pre>
<p>Next, I would apply this patch and compile, fixing up problems by hand (hey, porky.py is a prototype).  Then it was <code>hg qdiff</code> and the patch was up for review.  I could generate these patches <em>much</em> faster than they would have been able to be reviewed; this ended up being the bottleneck.</p>
<h4>Eventual goal for porky.py</h4>
<p>I&#8217;d like it to support this rewrite</p>
<pre>
rewrite FooToBar {
  class Foo => Bar {
    member mMember => member_
    method Method(a1, a2) => method(a2, a1)
  }
}
</pre>
<p>which would entail</p>
<ul>
<li>rename <code>class Foo</code> into <code>class Bar</code></li>
<li>rename type &#8220;Foo&#8221; into type &#8220;Bar&#8221; (including <code>Foo*</code>, <code>Foo&#038;</code>, &#8230;)</li>
<li>change calls to Foo constructors into Bar constructors</li>
<li>rename declaration of <code>Foo.mMember</code> into <code>Bar.member_</code></li>
<li>convert accesses of <code>((Foo)inst).mMember</code> into <code>((Bar)inst).member_</code>, (and similary for <code>inst->mMember</code>, &#8230;)</li>
<li>rename declaration of <code>Foo::Method</code> into <code>Bar::method</code></li>
<li>rename implementation of <code>Foo::Method</code> into <code>Bar::method</code></li>
<li>convert calls to <code>((Foo)inst).Method(a1, a2)</code> into <code>((Bar)inst).method(a2, a1)</code> (and similary for <code>inst->Method(a1, a2)</code>, &#8230; and similary for subclasses of Foo &#8230;)</li>
</ul>
<p>I should note that having porky.py rewrite <em>declarations</em> and <em>definitions</em> is not so important (though it would be nice!): there is only one declaration/definition.  Rewriting <em>uses</em> is much more important, since there are any number of uses.</p>
<p>I won&#8217;t implement this kind of rewrite until I need it.  Sorry!  But please feel free to dive in to the porky.py code and do it yourself!</p>
<h4>How porky.py fits into the &#8220;rewrite tool space&#8221;</h4>
<p>Rewrite tools have to trade off several factors.  It&#8217;s good to have a small, familiar DSL, as these are easier to learn and remember.  But it&#8217;s also good to have a large and expressive DSL, for raw rewrite power.  The table below is my attempt to fit porky.py into the space of relevant rewrite approaches I&#8217;m aware of.  It compares porky.py with</p>
<ul>
<li><em>pork</em>.  Rewrites specs are written in C++, which is not obscure to C++ programmers.  Rewrite specs are very verbose.  Any possible rewrite of C++ code can be expressed in pork.  Pork is very fast.
<li><em>XML+XSLT</em>.  Rewrite specs are written in XML/XSLT modeled on a particular C++ AST; very obscure.  Rewrite specs are relatively concise.  Any possible rewrite can be expressed.  Very slow.</li>
<li><em>Tree transformation</em> (e.g. in <a href="http://www.antlr2.org/doc/sor.html">ANTLR</a>).  Very obscure DSL.  Rewrite specs are relatively concise.  Can express (usually) any possible rewrite.  Usually relatively slow.</li>
<li><em><a href="http://coccinelle.lip6.fr/">Coccinelle/SmPl</a></em>.  DSL relatively familiar.  Rewrite specs concise.  Can express most statement-level rewrites.  Can be fast.</li>
<li><em>porky.py</em>.  DSL familiar.  Rewrite specs concise.  Express some expression-level rewrites.  Fast.</li>
<li><em>sed</em>.  DSL familiar.  Specs concise.  Extremely limited power.  Very fast.</li>
</ul>
<pre>
  	            <---- More LoC(bad) ----- Fewer LoC (good) --->
                    <-- Less obscure(good) -- More obscure(bad) -->

	               No DSL  |  Some DSL  |  More DSL  |  All DSL
                     +---------+------------+------------+-----------
        All possible |  Pork   |    ???     |    ???     |  XML+XSLT/tree trans.
	  ~Statement |         |            |coccinelle* |
	 ~Expression |         |  porky.py  |            |
	       Names |         |            |            |
 Crappy rename hacks | sed**   |            |            |
	-------------
 	 * only works for C code
	 ** assumption: regular expressions are well-known enough that
	    negative "DSL" connontations don't apply.
</pre>
<p>To be honest, the biggest lesson I learned from this project is that pork can be a good lower-level &#8220;engine&#8221; for higher-level tools.  I didn&#8217;t know about Coccinelle when I wrote porky.py; if I had, I might have tried retargeting it to pork instead of starting from scratch.  I prefer some of porky&#8217;s syntax/semantics to Coccinelle&#8217;s, but I think the additional complexity of SmPL adds a compelling amount of power over porky.py&#8217;s simpler DSL.  Upgrading SmPL to parse C++ and retargeting it to pork might be a good project for someone else.</p>
<p>But of course, since Coccinelle doesn&#8217;t understand C++, we&#8217;re &#8220;stuck&#8221; with porky.py for the foreseeable future <img src='http://blog.mozilla.com/cjones/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .</p>
<h4>Porky.py for language nerds</h4>
<p>Porky.py is implemented as a relatively simple source-to-source translator written in Python.  It converts porky.py specifications into a C++ header containing rewrite rules defined in a sort of &#8220;bytecode.&#8221;  This header is included by a general porky.py C++ tool that uses pork.  This tool &#8220;interprets&#8221; the rules, and if a rule matches part of the C++ AST, the tool generates a patch hunk according to the porky.py spec.  This is fairly similar to how a regular expression engine would implement a &#8220;replace&#8221; function, although the matching is obviously fairly different.</p>
<p>There were a few interesting problems that arose while I designed the porky.py language.  The first was what the semantics of rule matching should be.  The issue is that multiple rules can match the same program text.  For example, in the spec</p>
<pre>
call Foo => Bar
  (means "rewrite all calls to Foo into Bar, regardless of arguments")
call Foo(a, b) => Bar(b, a)
  (means "rewrite only the two-argument version of Foo into Bar, reverse the args")
</pre>
<p>both rules will match <code>Foo(1, 2)</code>.  Which should be used?.  My solution was use the most &#8220;specific&#8221; rule.  I defined what &#8220;specific&#8221; meant by the following rules.  First, a <code>call</code> pattern with arguments is &#8220;more specific than&#8221; a <code>call</code> pattern without arguments.  And second, a &#8220;literal&#8221; pattern is &#8220;more specific than&#8221; a wildcard pattern.  For example, <code>Foo::kSomething</code> is more specific than <code>f</code>.  Porky.py implements these heuristics by ordering all the rewrite rules at compile time by decreasing &#8220;specificity&#8221; and then attempting matches in that order.  The first rule to match is chosen for the rewrite.</p>
<p>A second issue that arose was how rewrite specifications should express &#8220;literal&#8221; patterns &#8212; i.e., match this exact text &#8212; vs. &#8220;wildcard&#8221; patterns &#8212; i.e., match any expression in this syntactic slot.  The problem arises in this rule <code>call Foo(Bar, a) => Baz(a, Bar)</code>.  Are &#8220;Foo&#8221;, &#8220;a&#8221;, and &#8220;Bar&#8221; literals or wildcards?  I didn&#8217;t want to add special syntax for wildcards because of the &#8220;minimal DSL&#8221; design goal.  So, my solution was to be as &#8220;greedy&#8221; as possible about choosing wildcard variables; I think this is likely to be least surprising.  In the example above, &#8220;Foo&#8221; shouldn&#8217;t be a wildcard because if it were, it would match any function call with two arguments.  That would be silly.  But, both &#8220;a&#8221; and &#8220;Bar&#8221; are wildcards; in fact, <em>any</em> identifier used as a C++ &#8220;expression variable&#8221; (other than function names) are treated as wildcards.  The &#8220;escape hatch&#8221; is C++ namespace qualification; if in the first example &#8220;Bar&#8221; was meant to only match some global symbol &#8220;Bar&#8221;, then the pattern could have been written as <code>call Foo(::Bar, a)</code>.  There are numerous other heuristics possible here, and I may change porky.py&#8217;s depending on feedback.</p>
<p>A third issue was how porky.py expressions should be typed, i.e., what their C++ type should be.  For example, this porky.py rule seems innocent enough <code>call foo->Bar() => foo->Baz()</code> when one is thinking &#8220;<code>foo</code> is a Foo instance,&#8221; but how can porky.py glean that information?  (Note that this is not a problem for the RHS &#8220;foo&#8221;, since its type is already known by the time porky.py is ready to generate a patch hunk.)  My solution to this was to have porky.py programmers write these LHS method calls in desugared form; in the example above, <code>call Foo::Bar(foo) => foo->Baz()</code>.  Eventually, though, I would like to use the <code>class</code> syntax I introduced above to resolve this ambiguity.  For example: <code>class Foo { call Bar => call Baz }</code> (note, though, that this isn&#8217;t implemented yet).  C++ inheritance also complicates things here.  When implementing porky.py I punted on inheritance (hey, it was five day&#8217;s work!), but I think the problems it presents have reasonable solutions.</p>
<h4>Hacking porky.py</h4>
<p>If you&#8217;re interested in taking up any of the porky.py extensions I suggested here, or just want some porky.py technical support, send me an e-mail at cjones@mozilla.com or drop by the #static channel at irc.mozilla.org.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.com/cjones/2009/08/04/introducing-porky-py-low-fat-pork/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Multi-process Firefox, coming to an Internets near you</title>
		<link>http://blog.mozilla.com/cjones/2009/06/21/multi-process-firefox-coming-to-an-internets-near-you/</link>
		<comments>http://blog.mozilla.com/cjones/2009/06/21/multi-process-firefox-coming-to-an-internets-near-you/#comments</comments>
		<pubDate>Mon, 22 Jun 2009 05:19:48 +0000</pubDate>
		<dc:creator>cjones</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[electrolysis]]></category>
		<category><![CDATA[multi-process]]></category>

		<guid isPermaLink="false">http://blog.mozilla.com/cjones/?p=20</guid>
		<description><![CDATA[Benjamin Smedberg recently discussed the motivation for splitting Firefox into multiple process, so I won&#8217;t recap that here.  Instead, I want to demonstrate what we&#8217;ve accomplished so far.  The video below shows our nearly Phase I-complete browser.  (Back and Forward don&#8217;t work yet, but are relatively easy to add.)
Sorry, your browser doesn&#8217;t [...]]]></description>
			<content:encoded><![CDATA[<p>Benjamin Smedberg <a href="http://benjamin.smedbergs.us/blog/2009-06-16/electrolysis-making-mozilla-faster-and-more-stable-using-multiple-processes/">recently discussed</a> the motivation for splitting Firefox into multiple process, so I won&#8217;t recap that here.  Instead, I want to demonstrate what we&#8217;ve accomplished so far.  The video below shows our nearly <a href="https://wiki.mozilla.org/Content_Processes#Phase_I:_Bootstrap">Phase I</a>-complete browser.  (Back and Forward don&#8217;t work yet, but are relatively easy to add.)</p>
<p><video src="http://people.mozilla.org/~cjones/ff-mp-demo.ogg" autobuffer controls>Sorry, your browser doesn&#8217;t support the &#8220;video&#8221; tag.  Try <a href="http://people.mozilla.org/~cjones/ff-mp-demo.ogg">clicking here</a> instead.</video></p>
<p>First, I browse around.  Nothing particularly exciting there, except that <em>two</em> Firefox programs are running &#8212; Firefox itself, and <code>gecko-iframe</code>.  The second program is new: it&#8217;s drawing the web pages to the screen.  Currently in Firefox, this is all done within the same program.</p>
<p>The fun comes when I <code>kill -9</code> this <code>gecko-iframe</code>, the &#8220;tab&#8221; containing mozilla.com.  To the non-geeky, invoking <code>kill -9</code> on a program causes it to crash IMMEDIATELY.  This simulates what would happen if, say, you tried to run a buggy plugin and it got itself into trouble.  Notice that only the &#8220;content&#8221; disappears when the page crashes; the user interface itself keeps running as if nothing happened.  This is a big step forward!  If I were to <code>kill -9</code> the current version of Firefox, everything would die, user interface and tabs.</p>
<p>With Firefox protected from buggy pages and plugins, more fun is possible.  This video shows me pressing a &#8220;Recover&#8221; button that relaunches the page that just crashed.  There are many more possibilities for recovering from these errors, and I&#8217;m excited to see what our user interface folks cook up.</p>
<p>This demo shows off a lot of hard work from Ben Turner, <a href="http://benjamin.smedbergs.us/blog">Benjamin Smedberg</a>, <a href="http://weblogs.mozillazine.org/bz/">Boris Zbarsky</a>, and <a href="http://blog.mozilla.com/joe">Joe Drew</a>.  (We also have plugins running in their own, separate processes, in an incomplete way.  However, the plugins still refuse to draw to the screen and so wouldn&#8217;t make for a very good demo.)  Drop by #content on IRC or read mozilla.dev.tech.dom if you want to find out more details of what the Electrolysis team is up to.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.com/cjones/2009/06/21/multi-process-firefox-coming-to-an-internets-near-you/feed/</wfw:commentRss>
		<slash:comments>54</slash:comments>
		</item>
		<item>
		<title>Farewell PRLock; I hardly knew thee</title>
		<link>http://blog.mozilla.com/cjones/2009/05/04/farewell-prlock-i-hardly-knew-thee/</link>
		<comments>http://blog.mozilla.com/cjones/2009/05/04/farewell-prlock-i-hardly-knew-thee/#comments</comments>
		<pubDate>Tue, 05 May 2009 05:56:54 +0000</pubDate>
		<dc:creator>cjones</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.mozilla.com/cjones/?p=11</guid>
		<description><![CDATA[The landing of bugs 58904 and 456272 have brought a new synchronization API to the Mozilla platform.  I think I&#8217;m safe in saying that the old API (PRLock, nsAutoLock, and friends) is deprecated in favor of the new.  But this is a good thing; you&#8217;ll prefer the new one, trust me.
The carrots
We&#8217;ve improved [...]]]></description>
			<content:encoded><![CDATA[<p>The landing of bugs <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=58904">58904</a> and <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=456272">456272</a> have brought a new synchronization API to the Mozilla platform.  I think I&#8217;m safe in saying that the old API (<code>PRLock</code>, <code>nsAutoLock</code>, and friends) is deprecated in favor of the new.  But this is a good thing; you&#8217;ll prefer the new one, trust me.</p>
<h4>The carrots</h4>
<p>We&#8217;ve improved the API in the following ways</p>
<ul>
<li>all classes are in the <code>mozilla</code> namespace</li>
<li>the &#8220;bare&#8221; primitives (<code>Mutex</code>, <code>Monitor</code>, <code>CondVar</code>) can now be allocated on the stack or as direct class members.  Their constructors use a proto-non-failing <code>malloc</code>, so your code will never see out-of-memory errors.</li>
<li>the primitives and their RAII wrappers (<code>MutexAutoLock/Unlock</code>, <code>MonitorAutoEnter</code>) provide methods to assert that the primitive is &#8220;owned,&#8221; or not, by the currently executing thread.  These should be used liberally in your code to enforce locking invariants (the assertions disappear in optimized builds).</li>
<li>the deadlock detector used by the new primitives in debug builds is asymptotically (and practically) more efficient than the old, should catch more deadlocks, and is now thread safe (!).</li>
</ul>
<h4>The sticks</h4>
<p>As with any change to core APIs, this one will require a lot of rewriting.  We&#8217;ll keep the old one around for a while, but new patches should use the new API.  (Aside: <a href="http://shawnwilsher.com/">Shawn Wilsher</a> has been an early adopter, for the storage code.  Check out what he&#8217;s been doing for some real-world examples.)</p>
<p>We&#8217;ve been extending our static analysis/refactoring tools to make upgrading old code easier.  Hopefully, few people will need to worry about this.  I&#8217;ll soon be blogging about our work; I think it&#8217;s a good example of how sweeping changes to existing code can be done quite easily, by one or two guys, in a matter of weeks.</p>
<p>The main change to the API that may cause some consternation is the removal of the <code>nsAutoLock::lock/unlock</code> and <code>nsAutoMonitor::Enter/Exit</code> methods from <code>MutexAutoLock</code> and <code>MonitorAutoEnter</code>.  It has been <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=486606#c1">decreed</a> that they are bad news.  Unfortunately, these are fairly difficult to rewrite automatically, so we may need to recruit a few module owners to help out.</p>
<h4>Further reference</h4>
<p>Most of the new API is documented on <a href="https://developer.mozilla.org/En/XPCOM_Thread_Synchronization">MDC</a>.  But please ping <code>cjones</code> on IRC if you have more questions or concerns.</p>
<p>[EDIT I see from PMO that I should be h4 and below.]</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.com/cjones/2009/05/04/farewell-prlock-i-hardly-knew-thee/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Hello</title>
		<link>http://blog.mozilla.com/cjones/2009/04/15/hello/</link>
		<comments>http://blog.mozilla.com/cjones/2009/04/15/hello/#comments</comments>
		<pubDate>Thu, 16 Apr 2009 04:03:42 +0000</pubDate>
		<dc:creator>cjones</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.mozilla.com/cjones/?p=9</guid>
		<description><![CDATA[Header image courtesy of the world-famous photographer rjones.  Yes, we&#8217;re related.  For legal purposes, I should probably note that the photo is released under the Creative Commons License, 2.0.
]]></description>
			<content:encoded><![CDATA[<p>Header image courtesy of the world-famous photographer <a href="http://www.flickr.com/photos/91829349@N00/">rjones</a>.  Yes, we&#8217;re related.  For legal purposes, I should probably note that the photo is released under the <a href="http://creativecommons.org/licenses/by/2.0/deed.en">Creative Commons License, 2.0</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.com/cjones/2009/04/15/hello/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
