<?xml version="1.0" encoding="UTF-8" ?>

<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
   
    <title>RealJenius.com - Category: journal</title>
   
   <link>http://realjenius.com</link>
   <description>I'm a software developer in the game industry, and have been (for better or worse) coding on the Java platform for the last decade. I also do all my own stunts.</description>
   <language>en-us</language>
   <managingEditor>R.J. Lorimer</managingEditor>
   <atom:link href="rss" rel="self" type="application/rss+xml" />
   
	<item>
  <title>Do not Upgrade Your (ve) to Ubuntu 12.04!</title>
  <link>http://realjenius.com/2013/02/06/media-temple-ve-and-ubuntu-1204/</link>
  <author>R.J. Lorimer</author>
  <pubDate>2013-02-06T00:00:00-08:00</pubDate>
  <guid>http://realjenius.com/2013/02/06/media-temple-ve-and-ubuntu-1204/</guid>
  <description><![CDATA[
     <p>A quick scan of my site shows that I&#8217;m typically one of <a href='http://www.mediatemple.net'>Media Temple&#8217;s</a> <a href='http://realjenius.com/tag/media%20temple/'>biggest supporters</a>. Their customer service is prompt, friendly, and their technological offering is always very stout for the price.</p>

<p>However, for the past little bit, I have been battling a rather unfortunate situation (which admittedly is not all their fault) regarding Ubuntu upgrades and their (ve) servers. My site currently runs on a <a href='http://mediatemple.net/webhosting/ve/'>Media Temple (ve)</a> hosting virtualized Ubuntu 10.04.4 LTS. I had been doing regular upgrades and dist-upgrades on this environment without fail, but I hit an issue where some of the packages in the Lucid Apt repos were just getting a little long in the tooth. I generally use Ruby, Nginx, and a few other things out there that have a tendency to move pretty quickly on their upgrades, and individual releases generally don&#8217;t introduce the major/minor package version upgrades of the sort that might happen with some of these components. Two and a half years can be a long time when it&#8217;s a server for a hobbyist exploring a lot of new tech.</p>

<p>Now, I do know that with Ubuntu&#8217;s community, you can inevitably dig up somebody who has a PPA that can be tied to your respective LTS install to individually bring in packages up to a newer version than that particular major release ships, but inevitably those are supported less effectively than the mainline distro packages, and there&#8217;s also a spidering of trust it results in, where you being relying on more than just &#8220;official&#8221; community package maintainers. This is, in fact, what I&#8217;ve had to do, however.</p>

<p>Choosing to leave the LTS wasn&#8217;t a huge deal for me anyway, as this is my personal server; not some commercially-hosted product. So, I decided to do the magical <code>do-release-upgrade</code> to level-up. Whoops.</p>

<p>Earlier last year if you decided to do a release-upgrade on Media Temple (ve)s with &#8220;normal&#8221; as your release profile (as specified in the <code>/etc/update-manager/release-upgrades</code> file), it would upgrade you to 10.10, and everything was shiny. You could then upgrade to 11.04, and even to 11.10. No problems.</p>

<p>However, if you tried to go to 12.04, the upgrade bombed very, very badly. In short, <a href='http://askubuntu.com/questions/146610/why-does-upgrading-to-12-04-on-an-openvz-vps-warn-that-the-kernel-size-is-0'>this is the error I received</a>.</p>

<blockquote>
<p>Please check your current kernel version with uname -r. If it is less than 2.6.24, the upgrade will fail half-way with a glibc error. That happens because the glibc included by default with 12.04 requires a minimum 2.6.24 kernel &#8211; glibc are the critical C libraries used by every application.</p>
</blockquote>

<p>Yup - sure enough, just as this link indicates, MediaTemple runs an <a href='http://openvz.org/Main_Page'>OpenVZ</a>-based virtualization by <a href='http://www.parallels.com/'>Parallels</a>. Here&#8217;s my <code>uname -r</code>:</p>

<pre><code>2.6.18-028stab101.1</code></pre>

<p>Uh-oh. 2.6.18 is definitely not 2.6.24. The forum Q&amp;A above suggests a rather ominous pinned dependency for <code>glibc</code>. I tried this temporarily, but never got it to work, and decided that it was not something I wanted to be shimmed on my server long-term anyway, so I went back to 10.04.</p>

<p><em>(Incidentally, this isn&#8217;t discussed much, but if an Ubuntu upgrade fails, you better have a spare boat handy, as this one is going to sink, and no bailing of water will help. It&#8217;s very difficult to do anything resembling a rollback without just restoring a backup. So be prepared!)</em></p>

<p>Now, something else happened shortly after 12.10 Ubuntu came out last year that made all of this muddier for Media Temple Ubuntinians. While 10.10 has been EOL for a while, it hasn&#8217;t actually been moved off of the main APT sources, so doing a &#8220;normal&#8221; upgrade would work as you&#8217;d expect. Through some administrative cleanup (I presume), it&#8217;s now properly under &#8220;old-releases&#8221; on the Ubuntu site. So if you try to upgrade from 10.04 LTS to 10.10 with <code>do-release-upgrade</code> and a normal upgrade setting, you will get a rather obscure 404 error. Worse, because Lucid isn&#8217;t actually in the EOL package tree for standard builds (because it&#8217;s not EOL), the general recommendation for upgrades fails (<a href='https://help.ubuntu.com/community/EOLUpgrades'>see here</a>). In short, they recommend you to:</p>

<ol>
<li>Move your current release sources to old-releases</li>

<li>Do a full &#8220;update+upgrade&#8221; to get caught up</li>

<li>Perform the do-upgrade-release to the next version, which may be EOL.</li>
</ol>

<p>This doesn&#8217;t work, as step-2 throws 404 errors. Now, I suspect so long as you did a full update before moving this over (flip steps one and two) it probably would work. But it feels rather unpleasant, and inevitably you&#8217;ll still hit 11.10 and have to stop. So now you&#8217;ve upgraded to a more recent build, but you&#8217;re no longer on an LTS release, and instead are on a release that will likely sunset in April, 2013, with nowhere to go.</p>

<p><strong>Even worse</strong> for most (ve) folks is the fact that the default upgade process is not to do a &#8220;normal&#8221; release, but to do an LTS upgrade on 10.04 now that 12.04 is out. So if you login to your Media Temple instance, it will suggest you upgrade to Precise, and if you do -<strong>BOOM</strong>- trashed install. I made that mistake as well during this process.</p>

<p>So in short, 10.04 LTS is probably the best you can do on a (ve) without doing some less-than-ideal workarounds, and the kernel is going to be 2.6.18 until Media Temple straightens it out.</p>

<p>To describe how old 2.6.18 actually is, 2.6.16 (just 2 patches prior) came out in <em>March of 2006</em>. 2.6.27, which came out over a year after was, at release, a long-term-support kernel for Linux - and even that was EOL&#8217;ed back in early 2012.</p>

<p>Now, to defend Media Temple a little bit, Ubuntu 10.04 LTS is still in active support, and will be for some time. So my distro is totally acceptable, even if the (admittedly, heavily patched and customized) kernel their virtualization uses is EOL. Also, from what I&#8217;ve been able to determine, this was originally a problem with Parallels, and not Media Temple. Unfortunately, it&#8217;s been something of a lacking priority for them, or at least not very transparent that it was a priority. Here is a forum thread that&#8217;s been going on since shortly after 12.04 went live: <a href='https://forum.mediatemple.net/topic/6345-ve-ubuntu-1204-lts/'>Ubuntu 12.04 LTS on Media Temple (ve)</a>.</p>

<p>Here are the most recent updates from Media Temple - November 6th of last year:</p>

<blockquote>
<p>We still don&#8217;t have a time frame as to when Ubuntu 12.04 LTS will be available for the (ve) Servers. The &#8216;technical obstacle&#8217; is we are bringing in a whole new infrastructure for our (ve) Servers. I apologize for the inconvenience but this is all the information I have for you at the moment.</p>
</blockquote>

<p>&#8230; and on January 11th this year:</p>

<blockquote>
<p>Hey there! Apologize for the inconvenience but we currently don&#8217;t have any update on when Ubuntu 12.04 LTS will be available.</p>
</blockquote>

<p>I even decided to bring this up with the Media Temple twitter team, and got a similar non-commital response unfortunately: <a href='https://twitter.com/realjenius/status/298973645991182337'>https://twitter.com/realjenius/status/298973645991182337</a>.</p>

<p>But, even with bad news comes good. The main reason for the delay seems to be that they are working on some rather large (and non-descript) infrastructural change for the (ve) servers. The one huge benefit so far is that they doubled their RAM offering for all (ve) tiers, and existing customers were allowed to upgrade with a simple push of a button. So I guess I shouldn&#8217;t complain too much!</p>
  ]]></description>
</item>

	<item>
  <title>JEP-171: Fence Intrisics Keep Memory In Line</title>
  <link>http://realjenius.com/2012/12/03/jep171-fences/</link>
  <author>R.J. Lorimer</author>
  <pubDate>2012-12-03T00:00:00-08:00</pubDate>
  <guid>http://realjenius.com/2012/12/03/jep171-fences/</guid>
  <description><![CDATA[
     <p>Doug Lea just posted a new Java enhancement proposal with <a href='http://openjdk.java.net/jeps/171'>JEP-171 - Fence Intrinsics</a>. This enhancement is all about exposing memory fence controls into Java code so that the <code>java.util.concurrent</code> APIs can more accurately and efficiently control memory ordering and bounding.</p>

<p>This is an interesting JEP as it proposes no Java consumer-oriented APIs; the only changes would be on the <code>sun.misc.Unsafe</code> class - which is already a fascinating pivot point for many of the advanced concurrency features of Java. Here is a Stack Overflow article that recaps many of them better than I could: <a href='http://stackoverflow.com/questions/5574241/interesting-uses-of-sun-misc-unsafe'>StackOverflow.com: &#8220;Interesting Uses of sun.misc.Unsafe&#8221;</a>. This class (as you can guess from the package) is <em>not</em> intended for regular Java devs to access; it&#8217;s an implementation-specific class, and is really only meant for internal use by class library devs on the JDK. <em>(That said, many folks have taken this class by the horns to wrangle the most out of the JVM anyway.)</em></p>

<p>What is proposed instead is to make ordering fences with memory a first-class citizen in the implementation layer of the JDK so that the various core APIs for concurrency can leverage fencing without having to resort on side-effects of other lower-level intrinsics (something that is done regularly today).</p>

<p>You may be asking why memory fencing is important. Modern CPUs can easily re-order memory accessing and storing when it can see via the upcoming instruction set that re-ordering will not impact the overall outcome of the program as considered by a single thread in the CPU. When you start throwing multiple threads or CPUs at a problem, out-of-order operations on memory that would otherwise go un-noticed could instead cause all kinds of data corruption and confusion. That&#8217;s why effectively all of the core synchronization and atomic operations in Java today implicitly carry a memory fence along with them; it&#8217;s part of the larger equation of protecting memory access.</p>

<p>This JEP includes three operations in the proposal:</p>

<ul>
<li><code>Unsafe.loadFence()</code> - Prevent reordering of load operations before this call with loads and stores after this call.</li>

<li><code>Unsafe.storeFence()</code> - Prevent reordering of store operations before this call with loads and stores after this call.</li>

<li><code>Unsafe.fullFence()</code> - Prevent reordering of <strong>all</strong> memory operations before this call with loads and stores after this call.</li>
</ul>

<p>You can read more about memory fences in the Wikipedia <a href='http://en.wikipedia.org/wiki/Memory_barrier'>Memory Barrier</a> article.</p>

<p>It&#8217;s worth noting that the JEP does consider potentially surfacing memory fence operations to full devs at some point in the future given that <code>sun.misc.Unsafe</code> is already platform specific (making it risky for external libs to access), and may become <em>impossible</em> to access given the efforts of Jigsaw:</p>

<blockquote>
<p>Adding these methods at the VM level permits use by JDK libraries in support of JDK 8 features, while also opening up the possibility of later exporting the base functionality via new java.util.concurrent APIs. This may become essential to allow people developing non-JDK low-level libraries if upcoming modularity support makes these methods impossible for others to access.</p>
</blockquote>
  ]]></description>
</item>

	<item>
  <title>The Madness of Tunneling JMX is Over!</title>
  <link>http://realjenius.com/2012/11/21/java7-jmx-tunneling-freedom/</link>
  <author>R.J. Lorimer</author>
  <pubDate>2012-11-21T00:00:00-08:00</pubDate>
  <guid>http://realjenius.com/2012/11/21/java7-jmx-tunneling-freedom/</guid>
  <description><![CDATA[
     <p>I work with an immense number of clients running our software, and in turn, an immense number of servers in the wild. Generally speaking, I am playing a role of support and debugging, and one of the facilities we leverage to the hilt in our platform to help us here is JMX.</p>

<p>MBeans give us a tremendous amount of access into the running system, and are a good standardized way to publish the management tools. Unfortunately, they are a tremendous pain in the ass to get access to in a secure system.</p>

<p>Generally what I am given for any system we connect to is my own SSH key or SSH credentials, and possibly one or two ports popped open with pinholes for my IP address. The latter I can provide for myself with SSH tunnelling if I need to. Unfortunately, this isn&#8217;t enough for JMX.</p>

<p>JMX runs on top of RMI, and as such, there are two ports that JMX utilizes:</p>

<ul>
<li>The JMX connect port.</li>

<li>The (infamously) roaming RMI data port.</li>
</ul>

<p>In all recent builds of Oracle Java, you can affix the first port via this system property when starting the Java program:</p>
<div class='highlight'><pre><code class='bash'>-Dcom.sun.management.jmxremote.port<span class='o'>=</span>1099
</code></pre>
</div>
<p>Unfortunately, the second port has no mechanism for assignment. This means that you either need (a) the entire firewall cracked wide open for your IP address, or (b) you need to run a dynamic socks proxy and route your particular JMX tool through the proxy. The latter is generally the only real option. You then have the added complexity that the hostname you connect to needs to match the value of <code>java.rmi.server.hostname</code>, which in cloud solutions that do complex things with IP addresses (I&#8217;m looking at your EC2), only makes it even harder to get right.</p>

<p>Thankfully (and I do mean thankfully), not anymore for systems running Java 7u4 or higher. <a href='http://hirt.se/blog/'>Marcus Hirt</a> has blogged about <a href='http://hirt.se/blog/?p=289'>the new RMI binding property</a> that has come to Java since the merger with JRockit.</p>

<blockquote>
<p>Now, one handy but often overlooked feature that entered the 7u4 JDK as part of the JRockit convergence, was the ability to specify the port of the RMI server. By setting the port used by the RMI registry and the RMI server to the same port, tunneling will be much easier. Now, the name of the property for setting the port of the RMI Server was slightly changed from the JRockit implementation, and is now called com.sun.management.rmi.port, instead of com.sun.management.rmiserver.port. Here is an example of how to enable the external management agent with the same RMI registry and RMI server port on the command line, in JDK 7u4 and later:</p>

<p>java -Dcom.sun.management.jmxremote.port=7091 -Dcom.sun.management.jmxremote.rmi.port=7091 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false</p>
</blockquote>

<p>I cannot stress enough how much this should help those of us dealing with firewalled systems and JMX. Kudos!</p>
  ]]></description>
</item>

	<item>
  <title>Good Week in Desktop Linux</title>
  <link>http://realjenius.com/2012/11/18/good-week-in-desktop-linux/</link>
  <author>R.J. Lorimer</author>
  <pubDate>2012-11-18T00:00:00-08:00</pubDate>
  <guid>http://realjenius.com/2012/11/18/good-week-in-desktop-linux/</guid>
  <description><![CDATA[
     <p>If you&#8217;re a desktop Linux user&#8230; and let&#8217;s face it, there are .86 of you for every 100 people who read this blog (hello one armed man!)&#8230; then this week was a good one. Let&#8217;s go through some of the news!</p>

<h2 id='elementary_os_luna_beta_1'>Elementary OS Luna Beta 1</h2>
<div class='thumbnail pull-right'>
	<img src='http://realjenius.com/images/articles/linux/elementary-luna.png' />
	
</div>
<p>One of the most watched Linux distros for some time has been <a href='http://elementaryos.org'>Elementary</a>. A number of GTK themes have come out of the work on the OS that have been some of the most well received in the Linux community.</p>

<p>This week <a href='http://elementaryos.org/journal/luna-beta-1-released'>Luna Beta 1 came out</a>, and it&#8217;s had a surprisingly positive number of reviews. Mine can be included in that. I have only installed it this weekend, but am already quite impressed with the polish and performance it has in comparison to Ubuntu 12.10.</p>

<p>Since Elementary is built on top of the Ubuntu platform, it benefits from the significant amount of packaging and community work that Ubuntu benefits from, and then there is simply an additional layer of polish and smart bundling of software that simply makes it feel like a much more complete and comfortable OS.</p>

<p>Now, that&#8217;s not to say it&#8217;s without bugs. I&#8217;ve had a few myself, including Noise (the custom media app) being unable to sync my music folder properly without crashing, and a number of system crash dialogs - but they have been relatively sparse so far. Overall, apps I&#8217;m used to having problems with in Linux (like Skype), have just worked; quite surprisingly.</p>

<p>Monday will be the first real test, as I will be entering the workforce with it full-time. So far, however, color me impressed!</p>

<h2 id='a_variety_of_steam_news'>A Variety of Steam News</h2>
<div class='thumbnail pull-left'>
	<img src='http://realjenius.com/images/articles/linux/steam.png' />
	
</div>
<p>Steam was officially launched to 1000 lucky folks on 11/06, and is starting to really pick up some&#8230; pressurized evaporated water. On Friday, the Valve folks <a href='http://blogs.valvesoftware.com/linux/the-great-winter-migration/'>announced 500 additional slots in their BETA</a>, slowly but surely expanding the test base.</p>

<p>It should be noted that <a href='http://news.yahoo.com/steam-linux-launches-beta-60-000-sign-first-183600349.html'>60,000 people signed up for the initial BETA</a>, which is not a paltry number. It&#8217;s an encouraging sign that there is at least some viability there.</p>

<p>In addition to 500 people being in the list, Friday also saw the official unveiling of <a href='http://store.steampowered.com/bigpicture/'>Big Picture mode</a> on the Linux client, which <a href='http://www.theverge.com/2012/11/16/3652756/valve-big-picture-mode-steam-os-linux-game-console'>some have seen as an opportunity for console-like gaming</a> from Linux (assuming, of course, that &#8216;if you build it, the games will come&#8217; holds true).</p>

<p>As I mentioned previously, the initial release had about <a href='http://www.pcgamer.com/2012/11/06/steam-linux-beta/'>25 games</a>, most of which were indie games that for one reason or another were already cross-platform and available through other channels, like <a href='http://www.humblebundle.com/'>Humble Indie Bundle</a>. That list has been gradually expanding over the last week, with a variety of other indie games and greenlight games coming alive. Which leads into the next topic&#8230;</p>

<h2 id='unity_3d_40__now_runs_on_linux'>Unity 3D 4.0 - Now Runs on Linux</h2>
<div class='thumbnail pull-right'>
	<img src='http://realjenius.com/images/articles/linux/unity.png' />
	
</div>
<p>One of the single most popular game engines right now is <a href='http://unity3d.com/'>Unity</a> (not to be confused with Ubuntu Unity). My company works with a ton of clients using this as their gaming platform, and there are a number of good reasons why; not the least of which is the huge number of platforms it supports out of the box.</p>

<p>The 4.0 release <a href='http://www.engadget.com/2012/11/15/unity-4-launch-linux-preview-directx-11-animation/'>includes preview support for generating Linux binaries</a>, which is a huge boon for Linux, as it effectively brings the porting effort down to zero. Since most Unity games don&#8217;t have any platform-specific code, it&#8217;s very easy to just generate the Linux distro to get the extra coverage.</p>

<h2 id='skype_41'>Skype 4.1</h2>
<div class='thumbnail pull-left'>
	<img src='http://realjenius.com/images/articles/linux/skype.png' />
	
</div>
<p>Microsoft <a href='http://ostatic.com/blog/skype-4-1-for-linux-brings-performance-improvements'>released Skype 4.1 this week for Linux</a>, bringing with it support for integration with the Messenger IM service.</p>

<p>This isn&#8217;t particularly notable as an individual release, but it does seem to further solidify the commitment (from Microsoft nonetheless!) to deliver a consistent, and hopefully quality, Skype client for Linux. Something those of us who use it for our jobs will appreciate.</p>

<h2 id='netflix_kinda'>Netflix (Kinda!)</h2>

<p>Finally, folks finally got Netflix (in all its Silverlight DRM glory) running on Linux via <a href='http://www.engadget.com/2012/11/17/netflix-finally-comes-to-linux-sort-of/'>use of Firefox running through Wine</a>. It apparently was quite a chore to get working; but you&#8217;ve gotta love the ingenuity of people.</p>
  ]]></description>
</item>

	<item>
  <title>JEP-155: New Concurrency Utils Part 1 - Atomically Delicious</title>
  <link>http://realjenius.com/2012/11/18/jep155-numerics/</link>
  <author>R.J. Lorimer</author>
  <pubDate>2012-11-18T00:00:00-08:00</pubDate>
  <guid>http://realjenius.com/2012/11/18/jep155-numerics/</guid>
  <description><![CDATA[
     <p>Concurrency geeks rejoice! Doug Lea and the JSR166 exper group are a perpetual fountain of classes, constructs, and frameworks for multi-threading, and they are at it once again; working to funnel more amazing roflscale concurrency primitives and not-so-primitives into Java 8 - this time in the form of <a href='http://openjdk.java.net/jeps/155'>JEP 155: Concurrency Updates</a>.</p>

<p>There are a number of enhancements being proposed in this JEP, so I&#8217;ll probably tackle it in a few blog posts. For today, we&#8217;ll talk numbers!</p>

<h2 id='atomicish_numbers'>Atomic-ish Numbers</h2>

<p>It&#8217;s very very common to use atomic values in metrics gathering capacities in Java application. Applications everywhere (if they know what is good for them) are doing things like tracking total execution time, # of executions, and max execution time for as many data points as they can stomach.</p>

<p>Compared to the &#8220;olden days&#8221; of Java, atomics (particularly <code>java.util.concurrent.atomic.AtomicLong</code>) are a huge boon for this as they get rid of the overhead caused by contention when you&#8217;re dealing with synchronization. A particular code-flow will be much more concurrent when updating an atomic value than trying to fence through a synchronization boundary in heavy traffic.</p>

<p>However, all is not well in atomic land. While they are much better than everything that has come before them, they can still be quite disruptive. Updating an atomic value is, by definition, still fully shared between threads. While it&#8217;s a narrow operation, the guarantee is that after the operation is done, all CPU active on the system will see the same value in that memory location. To do this, the CPU core doing the work has to ensure that the value of that atomic is pushed back out to main memory; not just retained in the CPU cache. And in so doing, it has to keep trying to update the core memory until the incremental is what is expected (via a CAS - <a href='http://en.wikipedia.org/wiki/Compare-and-swap'>compare and swap</a> operation). This CAS and memory fence ensures that staleness does not happen due to the CPU keeping data in local cache only, and not dumping out to slow system memory constantly.</p>

<p>However, this inherently means that, for this value, we <em>are</em> writing out to slow system memory constantly. So it&#8217;s not free. Additionally, what often can happen is that the atomic changing invalidates a line of cache shared by multiple values. This is fairly common because the contiguous cache blocks the CPU is designed to invalidate are generally large enough to hold multiple numeric values. This means that the CPU is forced to (unintentionally) re-fence multiple atomics; often atomics that are allocated together for the same data structure.</p>

<p>This lack of cache coherence and affinity can be a very real, and very hidden cost with all fence operations. Martin Thompson and Michael Barker (the wizards behind the much discussed <a href='http://martinfowler.com/articles/lmax.html'>LMAX Architecture</a> and the <a href='http://lmax-exchange.github.com/disruptor/'>disruptor stream processing framework</a>) have a talk that covers this problem (and many others) in detail titled <a href='http://www.infoq.com/presentations/Lock-free-Algorithms#HN2'>Lock-Free Algorithms</a>.</p>

<p>Thompson and Barker show exactly how much this cache issue can impact performance, and how with a little adjusting, the atomic classes can be designed with what they call &#8220;mechanical sympathy&#8221; in mind; in other words, built to avoid sharing cache regions with other atomic values. So instead of this:</p>
<div class='highlight'><pre><code class='text'>cache line 1 . . . . &lt;atomic int val A&gt; . . . . . &lt;atomic int val B&gt; . . .
cache line 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
</code></pre>
</div>
<p>You ideally would get this:</p>
<div class='highlight'><pre><code class='text'>cache line 1 . . . . &lt;atomic int val A&gt; . . . . . . . . . . . . . . . . .
cache line 2 . . &lt;atomic int val B&gt; . . . . . . . . . . . . . . . . . . .
</code></pre>
</div>
<p>Now the two values are isolated from each other, reducing cache damaging significantly.</p>

<p>While I&#8217;m listing interesting related reads, another article just popped up in the past couple days that shows some very real metrics for the problems you can hit with Atomics in terms of program throughput. Marc Brooker <a href='http://brooker.co.za/blog/2012/11/13/increment.html'>just posted how atomics and volatiles in Java work on x86</a>, and it shows exactly what a lack of mechanical sympathy can mean to your cache hit performance. The <code>perf stat</code> output he shows with the significant increase of <code>LLC-load-misses</code> is exactly what this padded cache is meant to mitigate as much as possible - of course, it can only do so much; the entire idea of an atomic implies there is some shared memory involvement, which is simply going to be slower. The goal is to narrow that slowness to specific values, as much as possible.</p>

<p>So mechanical sympathy changes help, but only get you so far. The work in JEP-155 doesn&#8217;t stop by exploring this idea. There is another issue with atomics as it pertains to being used for metrics-like monitoring in large scale Java systems. Their atomic requirement may actually be too stringent. Often times when you&#8217;re looking at something like an &#8220;average&#8221; execution time or &#8220;max&#8221; execution time, it&#8217;s acceptable to say the value can be eventually consistent across multiple updates. If there is a little margin for error (like you might miss one recent update on a read), it&#8217;s not going to impact your analysis in any real way.</p>

<p>Knowing this, the JSR166 folks have taken one of the ideas that are common in highly concurrent programming, and applied them to these types: striping, or segmenting.</p>

<p>If you&#8217;ve ever looked into the internals of the <code>ConcurrentHashMap</code> class, you may be familiar with the constructs it uses to minimize contention and avoid locking. Internally, the CHM uses a series of segments which represent sub-sections of the map, and can be worked with independently. By using multiple segments, the data structure is able to immediately divide the potential contention, at the expense of a little more memory used.</p>

<p><em>(Incidentally, the fastest JDBC connection pool I&#8217;ve ever benchmarked at scale uses this same mechanic to avoid pool contention - see <a href='https://github.com/wwadge/bonecp'>BoneCP</a>.)</em></p>

<p>This same idea is in place for a number of new atomic classes. There is an abstract <code>Striped64</code> super-class that holds a collection of <code>Cell</code> objects, which are really just Atomics with special padding to help with mechanical sympathy. The cells are created lazily as CAS updates fail due to contention. What this means is that a single instance of this may have several internal atomics representing the value in the aggregate. Since this class doesn&#8217;t just sit on the CAS wall until it updates successfully, it doesn&#8217;t have the same repeated crawling down into shared memory from the CPU cache. Instead it will retry a set number of times, and if it can&#8217;t get the first cell to update, it creates another one. The next one is a fully separate atomic in memory, and is bound by its own memory fencing and contention.</p>

<p>What&#8217;s interesting about this is since the atomics are intentionally written to avoid cache collisions, each one can be independently represented on a CPU, and since the class will try to balance the cells to individual threads, it will avoid causing the painful contentious updates altogether, making the most valuable use of the atomics. Each thread can say &#8220;If I created a new cell because a previous cell was contentious, I&#8217;ll keep using that new cell&#8221; - this means that CAS collisions can theoretically be eliminated over time, with the expense of potentially creating a larger memory footprint for a single number.</p>

<p>Since the cells are all independently update-able and create-able, and based on multiple iterative passes, the process of calculating a value over them involves iterating each cell and getting a snapshot value from them independently. Because of that, it&#8217;s possible that during the iteration, some of the cells may be slightly out of date or non existent on my local thread.</p>

<p>Additionally, since this is all based on combining the values out of multiple cells together, it immediately implies that there are only certain accumulative operations where this segmentation can be used.</p>

<p>There are several new classes that extend <code>Striped64</code> to provide relaxed-consistency classes for cases where you want to accumulate values in this way:</p>

<ul>
<li><code>LongAdder</code>; <code>DoubleAdder</code> - Classes that allow threads to accumulate values into a long or double in a thread-safe, and extremely low-contention path. <strong>Example Usage:</strong> Accumulating total execution time for a particular call so you can calculate average execution time.</li>

<li><code>LongMaxUpdater</code>; <code>DoubleMaxUpdater</code> - Classes that allow threads to calculate the &#8220;max&#8221; value seen up to a point, again in a very low-contention implementation. <strong>Example Usage:</strong> Tracking the max execution time for a particular method call.</li>

<li><code>LongAdderTable</code> - A handy extrapolation of long adder into a hash table form. This is an optimized map of LongAdders (although it doesn&#8217;t implement the Map interface for a number of reasons) that is specifically designed to be as efficient as possible in the use of long adder values per key, and allows for decrementing, incrementing, and adding by key. It also will create the adders for you automatically simply as an operation of you incrementing. <strong>Example Usage:</strong> Tracking several call execution times for an application all in one data structure.</li>
</ul>

<p>Let&#8217;s look at how these classes work internally to bring home the idea of cells for contention management. If we look at the <code>LongAdder</code> class as an example - let&#8217;s say we have a simple counter value we&#8217;re tracking for some method call, and it looks like this at one point:</p>
<div class='highlight'><pre><code class='text'>LongAdder
|
*-- Cell[0] = 51352
</code></pre>
</div>
<p>Our thread comes in to increment the first cell and we keep getting a CAS collision. So, based on the collision heuristics, we decide to create a new cell and increment there:</p>
<div class='highlight'><pre><code class='text'>LongAdder
|
*-- Cell[0] = 51494
|
*-- Cell[1] = 1
</code></pre>
</div>
<p>Note that Cell[0] has incremented several times outside of our control (other threads), and we also created Cell[1] to hold our new value.</p>

<p>To calculate the sum total for this long adder, we simply sum all of the cells together, returning <code>51495</code>.</p>

<p><em>The internal documentation on the <a href='http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/jsr166e/Striped64.java?view=markup'>Striped64</a> draft class has phenomenal notes on the algorithm)</em>.</p>

<p>While discussing atomic numbers, it should also be noted that there are implementations of <code>AtomicDouble</code> and <code>AtomicDoubleArray</code> laid out in the extras package of this draft work as well. These would ideally bring true atomic floating point to Java for the first time, but as indicated on the draft group site, the extras folder is probably not going to make it into Java 8 directly. They do show how these can be implemented, however, which is a feat in and of itself.</p>

<h2 id='whats_next'>What&#8217;s Next?</h2>

<p>There&#8217;s a good bit more in the JEP-155 bundle, including stamped locks and some nifty fork join improvements. Those are for another time, however.</p>
  ]]></description>
</item>

	<item>
  <title>Value Objects Proposal in Java with JEP 169</title>
  <link>http://realjenius.com/2012/11/10/values-objects-in-java/</link>
  <author>R.J. Lorimer</author>
  <pubDate>2012-11-10T00:00:00-08:00</pubDate>
  <guid>http://realjenius.com/2012/11/10/values-objects-in-java/</guid>
  <description><![CDATA[
     <p>There have been a lot of <a href='http://openjdk.java.net/jeps/0'>interesting JEPs</a> proposed recently for Java. With the pending onslaught of <a href='http://openjdk.java.net/projects/lambda/'>Lambdas</a>, and with them, an entirely new programming model, there is a whole new set of enhancements and opportunities for both the language and the JVM to expand.</p>

<p>One of the recently announced JEPs is <a href='http://openjdk.java.net/jeps/169'>JEP 169 - Value Objects</a>. Value objects are a number of tools for expicitly declaring that a Java object represents a raw set of vectorize-able values, rather than a composite set of memory values linked via pointers, and dynamically allocated on the heap.</p>

<p>As Java programmers, most of us are comfortable with (even if not entirely happy with) the distinction between primitives and objects. It&#8217;s one of those ugly, very un-academic pragmatics that you deal with because of the benefits it brings. Unfortunately, as the aforementioned JEP mentions, it&#8217;s also an ugly dividing line. You find yourself choosing between very low-level and hard-to-manage data structures and value types, or choosing more manageable high-level types, sacrificing the performance gains you would see otherwise:</p>

<blockquote>
<p>In modern JVMs, object allocation is inexpensive, with a cost comparable to out-of-line procedure calling. But even this cost is often a painful overhead when compared to individual operations on primitive values. Thus, Java programmers face a binary choice between existing primitive types (which avoid allocation) and other types (which allow data abstraction and other benefits of classes). When they need to define small composite values such as complex numbers, pixels, or pairs of return values, neither approach serves. This dilemma often has no good solution, and the workarounds distort Java programs and APIs. Consider, for example, the lack of a good complex number type for those who program numeric algorithms in Java.</p>
</blockquote>

<p>The general idea is allow programmers to give the JVM more knowledge about objects that are already designed to be immutable and simply represent a value, so that it can be treated in a more efficient way; much like primitives.</p>

<p>The example that is used repeatedly in the JEP is a class that represents a Complex number; call it <code>java.lang.Complex</code>. As you may or may not know, Java today doesn&#8217;t have a complex number value type. There are a number of open-source and academic examples of creating one, with the commonality between them being that they are written as a Java object. Usually, they are represented as a couple <code>double</code> values internally, and they have a numbef of methods for doing things like adding, subtracting, dividing, calculating cosine, and so forth. <a href='http://commons.apache.org/math/userguide/complex.html'>Apache-Commons Math</a> has a perfect example.</p>

<p>However, if you think about it, there is really no reason this Complex value has a full heap allocated object. It&#8217;s really just a couple primitives that are bound together inextricably. But the only way to do this with pure primitives would be to juggle multiple primitive values manually, and that&#8217;s not exactly a pretty API: hard to explain to implementors, and very hard to add functionality around. Sadly, a lot of APIs that have to deal with quickly shuffling numeric values (such as rendering APIs) fall into the trap of having to deal with buckets o&#8217; numbers.</p>

<p>This JEP is an attempt at tackling this problem. Once an object has been declared a value object, it can now be scalarized by the VM into a compact binary representation that can be propagated on the stack, and can even be interned in memory. In other words, the VM can treat the Complex class exactly like two <code>double</code> values held in a single memory vector; but the developer code can still handle it like an object, with all of the encapsulation and behavioral binding that implies.</p>

<p>Because the value object is being treated like a primitive, it now has no surrogate identity (no pointer location), and as such, it can&#8217;t be used for operations like synchronization and reference equality checks.</p>

<h2 id='boxing_benefits'>Boxing Benefits</h2>

<p>One of the interesting notes about this proposal is the fact that it changes the cost and complexity of boxing and unboxing of values from primitive types and back. Consider this contrived example:</p>
<div class='highlight'><pre><code class='java'><span class='kd'>public</span> <span class='kt'>void</span> <span class='nf'>someMethod</span><span class='o'>()</span> <span class='o'>{</span>
	<span class='kt'>int</span> <span class='n'>val1</span> <span class='o'>=</span> <span class='mi'>5</span><span class='o'>;</span>
	<span class='kt'>int</span> <span class='n'>val2</span> <span class='o'>=</span> <span class='mi'>10</span><span class='o'>;</span>
	<span class='kt'>int</span> <span class='n'>result</span> <span class='o'>=</span> <span class='n'>sumofsquares</span><span class='o'>(</span><span class='n'>a</span><span class='o'>,</span> <span class='n'>b</span><span class='o'>));</span>
	<span class='c1'>// ...</span>
<span class='o'>}</span>

<span class='kd'>public</span> <span class='n'>Integer</span> <span class='nf'>sumofsquares</span><span class='o'>(</span><span class='n'>Integer</span> <span class='n'>a</span><span class='o'>,</span> <span class='n'>Integer</span> <span class='n'>b</span><span class='o'>)</span> <span class='o'>{</span>
	<span class='k'>return</span> <span class='nf'>square</span><span class='o'>(</span><span class='n'>a</span><span class='o'>)</span> <span class='o'>+</span> <span class='n'>square</span><span class='o'>(</span><span class='n'>b</span><span class='o'>);</span>
<span class='o'>}</span>

<span class='kd'>public</span> <span class='n'>Integer</span> <span class='nf'>square</span><span class='o'>(</span><span class='n'>Integer</span> <span class='n'>val</span><span class='o'>)</span> <span class='o'>{</span>
	<span class='kt'>int</span> <span class='n'>val</span> <span class='o'>=</span> <span class='n'>val</span><span class='o'>.</span><span class='na'>intValue</span><span class='o'>();</span>
	<span class='k'>return</span> <span class='n'>val</span> <span class='o'>*</span> <span class='n'>val</span><span class='o'>;</span>
<span class='o'>}</span>
</code></pre>
</div>
<p>In this case, we have two primitive values in <code>someMethod()</code>, but immediately pass them into a method that expects boxed types. As such, the compiler is going to secretly inject code like this: <code>sumofsquares(Integer.valueOf(val1), Integer.valueOf(val2))</code>.</p>

<p>What this new value objects support would allow the compiler and runtime to do is defer any of boxing all the way until some complex behavior is invoked on the type - in this case that would be the <code>intValue()</code> invocation within the <code>square</code> method. However, since the compiler can determine it&#8217;s simply calling a method that returns the value component contained there-in, it can actually completely eliminate the boxing altogether.</p>

<p>The method tree then turns around and returns a boxed value again, but the compiler and runtime can again eliminate any boxing, as the method tree never deals with them in a complex way.</p>

<p>Therefore, somewhat surprisingly, the boxing to a reference style <code>java.lang.Integer</code> above can in fact be eliminated completely. The other exciting benefit is that your own value types can be treated this same way, even though (unlike <code>int</code> and <code>Integer</code>) there is no native primitive value directly representing your type. This opens a whole new opportunity for expressive and clean APIs that have to deal with primitives, closing many of the difficult &#8220;performance vs. readable&#8221; problems Java developers have faced.</p>

<h2 id='class_vs_object'>Class vs Object</h2>

<p>Several months ago I watched a presentation from Brian Goetz (can&#8217;t find the specific talk) where he discussed the potential for value objects in Java&#8217;s future, and at the time the thought was that it could be a new keyword or annotation on the type that indicated it was a value type. This proposal, however, discusses using a per-instance locking mechanism similar to:</p>
<div class='highlight'><pre><code class='java'><span class='n'>Integer</span> <span class='n'>x</span> <span class='o'>=</span> <span class='k'>new</span> <span class='n'>Integer</span><span class='o'>(</span><span class='mi'>123456</span><span class='o'>);</span>
<span class='c1'>// Not yet a value object...</span>
<span class='n'>x</span> <span class='o'>=</span> <span class='n'>x</span><span class='o'>.</span><span class='na'>lockPermanently</span><span class='o'>();</span>
<span class='c1'>// Now a value object...</span>
</code></pre>
</div>
<p>There are some benefits to this manual locking:</p>

<ul>
<li>You can use some objects as reference types; if you&#8217;re synchronizing on Integer somewhere in your code (Why?) this would allow you to continue to do so.</li>

<li>Initialization of objects that will eventually be value types can be done in multiple steps.</li>

<li>Even if your code (or some library you use) doesn&#8217;t mark the object as a value type explicitly, the JIT can still analyze the usage of the object, and transliterate it to a value type internally as a form of runtime optimization.</li>
</ul>

<p>This idea of value objects becomes a huge benefit when exploring expressive sophisticated functional programming models. Since one of the main tenants of functional programming is immutable types - if Java can in turn represent those immutable types as primitive values, it helps ensure that functional programming models don&#8217;t pay a penalty for their expressivity and immutability.</p>
  ]]></description>
</item>

	<item>
  <title>Steam for Linux Beta Released; Nvidia Making In-Roads</title>
  <link>http://realjenius.com/2012/11/06/steam-linux-official/</link>
  <author>R.J. Lorimer</author>
  <pubDate>2012-11-06T00:00:00-08:00</pubDate>
  <guid>http://realjenius.com/2012/11/06/steam-linux-official/</guid>
  <description><![CDATA[
     <div class='thumbnail pull-right'>
	<img src='http://realjenius.com/images/articles/linux/steam.png' />
	
</div>
<p>Today, Valve released the <a href='http://www.pcmag.com/article2/0,2817,2411827,00.asp'>Steam for Linux beta client</a> (<a href='http://www.zdnet.com/big-time-gaming-coming-to-linux-7000006997/'>more</a>, <a href='http://www.brightsideofnews.com/news/2012/11/6/valve-moves-to-change-pc-gaming-steam-goes-linux.aspx'>and more</a>) to 1000 lucky testers. It&#8217;s an exciting official event (I <a href='http://realjenius.com/2012/11/02/valve-steam-uds/'>discussed this previously</a>), and while the <a href='http://store.steampowered.com/search/?snr=1_4_4__12&amp;term=linux#os=linux&amp;advanced=0&amp;sort_order=ASC&amp;page=1'>supported game list is still quite small</a>, there is no surprise that nearly all of the humble indie bundle games that went to Linux are also available on Steam.</p>

<p>On another note, while there is a certain bit of &#8220;layman&#8221; reporting in this, I thought this was a surprising report from the Register on <a href='http://www.theregister.co.uk/2012/11/06/nvidia_heralds_steam_for_linux/'>Nvidia releasing &#8216;double-speed&#8217; drivers</a>. <a href='http://www.engadget.com/2012/11/06/nvidia-valve-geforce-linux-drivers-r310/'>Engadget has a more technical</a> walkthrough as well.</p>

<p>It was only a couple of months ago that <a href='http://www.wired.com/wiredenterprise/2012/06/torvalds-nvidia-linux/'>Linus gave Nvidia the finger</a>, and there is good reason for that - so as an Nvidia card owner, I&#8217;m glad to see that Valve has encouraged to consume a large in-flow of patches and contributions to help them make their Linux offering less horrible.</p>

<p>In reality, the drivers they are releasing only fix performance for a few cards and likely for specific problems found from the Source engine, but even still, a little traction can go a long way. There have been a lot of announcements of potential Linux support recently between Valve, <a href='http://blogs.unity3d.com/2012/07/03/linux-publishing-preview-what-how-and-wherefore-3/'>Unity3d for Linux (which is used aggressively in the indie space)</a>, <a href='http://news.softpedia.com/news/Space-Sim-Star-Citizen-Is-Getting-Closer-to-a-Linux-Release-304249.shtml'>Star Citizen by Chris Roberts (ala Wing Commander)</a>, and of course <a href='http://www.omgubuntu.co.uk/2012/09/humble-indie-bundle-6-arrives-with-6-linux-games-in-tow'>Humble Indie Bundle</a>, things are starting to finally look up for Linux gamers!</p>

<p>In closing, here is Linus giving his sign language to Nvidia:</p>
<div><notextile>


	


<iframe frameborder='0' height='315' id='ytplayer' src='http://www.youtube.com/embed/_36yNWw_07g?origin=http://realjenius.com' type='text/html' width='560'><!--x--></iframe>



</notextile>
</div>
  ]]></description>
</item>

	<item>
  <title>Atlassian OnDemand Drops Fisheye</title>
  <link>http://realjenius.com/2012/11/05/atlassian-drops-svn-fisheye/</link>
  <author>R.J. Lorimer</author>
  <pubDate>2012-11-05T00:00:00-08:00</pubDate>
  <guid>http://realjenius.com/2012/11/05/atlassian-drops-svn-fisheye/</guid>
  <description><![CDATA[
     <div class='thumbnail pull-right'>
	<img src='http://realjenius.com/images/articles/atlassian/ondemand_logo_landing.png' />
	
</div>
<p>The folks over at Atlassian have been providing some form of hosted JIRA+code for some time - starting with a variety of variants of what they called &#8220;JIRA Studio&#8221;, up to their most current cumulonimbus offering: <a href='http://www.atlassian.com/software/ondemand/overview'>Atlassian OnDemand</a>.</p>

<p>My company has been using these hosted forms of the Atlassian suite for upwards of three years now for a variety of things:</p>

<ul>
<li>Issue Tracking</li>

<li>Code Repository</li>

<li>Internal Documentation</li>

<li>Client Support Tools</li>

<li>Code Reviews and Auditing with FishEye</li>

<li>CI Builds with Bamboo</li>
</ul>

<p>At the time we signed up, the &#8220;Belle of the Ball&#8221; was <a href='http://www.atlassian.com/software/fisheye/overview'>FishEye</a> with Subversion, and it has served us fairly well, overall. I will be the first to admit that it&#8217;s had its warts too, as most of you familiar with SVN are probably not surprised. It&#8217;s only been in about the past year or so that the Atlassian folks have supported any other legitimate options for VCS, and because of the sheer volume of code that we interact with at any point in time between our own products and clients we work with, we have stuck with SVN up to this point. Mountain moving takes time after all.</p>

<p>In a move that wasn&#8217;t entirely disappointing, but certainly felt aggressive, Atlassian recently announced that they are <a href='http://go-dvcs.atlassian.com/display/EOL/Source+Review+Bundle+End+of+Service'>dropping support for hosted Subversion altogether</a> - and they&#8217;re taking FishEye out along with it.</p>

<p>Looking back at the various blog entries, open tickets, and other breadcrumbs I found while frothing for better VCS support over the past couple years, I suppose I should&#8217;ve been able to read the tea leaves and see this one coming. They have been putting all of their feature effort into <a href='https://bitbucket.org/'>BitBucket</a> after they bought it, and have made it clear that it was their direction for the future for some time now.</p>

<p>I suppose at some level I don&#8217;t blame them; FishEye is notorious for the amount of horsepower it requires (having been in a self-hosted environment with it previously, I can attest to this), and frankly, so is Subversion given the relatively poor delta management and the centralized nature of it - since one begets the other, I can imagine that it&#8217;s a rather ugly hosting proposition. Our experience over the past few years with hosted FishEye has been mediocre at best; the tool is very capable, but the performance in the on-demand space has been hit and miss.</p>

<p>Nonetheless, I found it rather surprising how quickly they have chosen to force the retirement. The cut-over is happening by October of 2013; I wouldn&#8217;t be surprised if that date moves some (often times their EOL dates do), but all the same, they are not doing any hand-waving about keeping SVN around.</p>

<p>At this point the move to BitBucket/DVCS will comfortably replace most of the features that FishEye has that we actually use, including code reviews and web-based browsing of the code; and of course, Git and Mercurial are both capable of replacing SVN whole-hog - it&#8217;s really just a matter of the system-administration and ramp-up for the team.</p>
  ]]></description>
</item>

	<item>
  <title>Valve Engineering at Ubuntu Developer Summit</title>
  <link>http://realjenius.com/2012/11/02/valve-steam-uds/</link>
  <author>R.J. Lorimer</author>
  <pubDate>2012-11-02T00:00:00-07:00</pubDate>
  <guid>http://realjenius.com/2012/11/02/valve-steam-uds/</guid>
  <description><![CDATA[
     <p>There&#8217;s been a lot of press and coverage of Valve&#8217;s <a href='http://www.ubuntuvibes.com/2012/10/valve-linux-more-viable-than-windows-8.html'>acerbic comments regarding Windows 8</a>, so the fact that Steam is coming to Linux is probably not a surprise to anybody.</p>

<p>As a Linux-as-my-primary-desktop user (one of the paltry few) it&#8217;s exciting for me to see this coming. I currently dual boot to Windows 7 to do all of my PC gaming, but choose Linux for my dev environment because it&#8217;s tremendously more productive on any given day, for many of the same reason many devs prefer OS X (first-class terminal, high-quality integration with various VCS, etc).</p>

<p>I don&#8217;t know if this gamble by Valve will pay off in the long run, but I&#8217;m hopeful that it will. Things have really started to shift away from Windows-only in the past few years, and whatever the final form, I think that&#8217;s tremendously healthy.</p>

<p>Here&#8217;s Drew Bliss from Valve talking at UDS this year about their motivation, short-term plans, and overall goals for Steam on Linux:</p>
<div><notextile>


	


<iframe frameborder='0' height='315' id='ytplayer' src='http://www.youtube.com/embed/vNrrpnPlBrk?origin=http://realjenius.com&amp;t=13m10s' type='text/html' width='560'><!--x--></iframe>



</notextile>
</div>
<p><em>(via <a href='http://www.reddit.com/r/Ubuntu/comments/12f04e/drew_bliss_from_valve_at_uds/'>Reddit</a>)</em></p>
  ]]></description>
</item>

	<item>
  <title>Notice: Site Update</title>
  <link>http://realjenius.com/2012/11/02/site-updates/</link>
  <author>R.J. Lorimer</author>
  <pubDate>2012-11-02T00:00:00-07:00</pubDate>
  <guid>http://realjenius.com/2012/11/02/site-updates/</guid>
  <description><![CDATA[
     <p>I just did a pretty big refresh of my site on the backend. The only change that should impact folks directly is that the feed URLs changed:</p>

<ul>
<li><code>/feed</code> is now <code>/atom.xml</code></li>

<li><code>/category/[...]/feed</code> is now <code>/category/[...]/atom.xml</code></li>

<li><code>/tag/[...]/feed</code> is now <code>/tag/[...]/atom.xml</code></li>
</ul>

<p>I&#8217;ve put in some 301s for those URLs, so hopefully feeds will automatically update for you.</p>

<p>If you have any issues with the site (links that don&#8217;t work, etc) please <a href='http://realjenius.com/contact.html'>let me know</a>!</p>
  ]]></description>
</item>

</channel>
</rss>