<?xml version="1.0" encoding="UTF-8"?>
<feed version="0.3" xmlns="http://purl.org/atom/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xml:lang="en">
  <title>Squawks of the Parrot</title>
  <link rel="alternate" type="text/html" href="http://www.sidhe.org/~dan/blog/" />
  <modified>2009-05-21T00:55:18Z</modified>
  <tagline>Dan natters on about, well, stuff.</tagline>
  <id>tag:www.sidhe.org,2009:/~dan/blog/1</id>
  <generator url="http://www.movabletype.org/" version="2.661">Movable Type</generator>
  <copyright>Copyright (c) 2009, Dan</copyright>
  <entry>
    <title>Gluten free chocolate cake</title>
    <link rel="alternate" type="text/html" href="http://www.sidhe.org/~dan/blog/archives/000472.html" />
    <modified>2009-05-21T00:55:18Z</modified>
    <issued>2009-05-20T20:55:18-05:00</issued>
    <id>tag:www.sidhe.org,2009:/~dan/blog//1.472</id>
    <created>2009-05-21T00:55:18Z</created>
    <summary type="text/plain">I&apos;m happily food-issue free, but I&apos;ve some friends who do have trouble with a variety of things. Gluten&apos;s a common problem, as is cow dairy, so this cake has neither. It makes enough for two 9&quot; rounds. It&apos;s also got as smooth a texture as a regular wheat flour cake (no rice flour grit!) and it doesn&apos;t even take much work to get there. It does take some time (the recipe takes about two hours, end to end) and some abuse (hence the blender). Rice flour actually works pretty well in things you&apos;d use wheat flour for but don&apos;t need...</summary>
    <author>
      <name>Dan</name>
      <url>http://www.sidhe.org/~dan/blog/</url>
      <email>dan@sidhe.org</email>
    </author>
    
    <content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.sidhe.org/~dan/blog/">
      <![CDATA[<p>I'm happily food-issue free, but I've some friends who do have trouble with a variety of things. Gluten's a common problem, as is cow dairy, so this cake has neither. It makes enough for two 9" rounds. It's also got as smooth a texture as a regular wheat flour cake (no rice flour grit!) and it doesn't even take much work to get there. It does take some time (the recipe takes about two hours, end to end) and some abuse (hence the blender).</p>

<p>Rice flour actually works pretty well in things you'd use wheat flour for but don't need gluten (so good for cakes and pies, bad for bread and cream puffs) but the stuff you can get at the market is damned gritty. (Check the ethnic food section -- my Stop 'n Shop has it for about half the price of the big box 'organic' food places) I've been told you can pick up food mills that'll get it as fine as wheat flour, but I don't use it nearly enough to warrant the expense, so I'm stuck with the rough stuff.</p>

<p>All flours you use in cakes work by hydrating, or soaking up water. How fast flour hydrates is largely function of the grain and the grind. Finely ground flour soaks in water faster than a rough grind, and different grains (wheat, rice, sorghum, or whatever) soak at different rates as well.</p>

<p>Rice flour is perfectly happy to soak up the water and get nice and smooth but the rough grind means it takes ages for the water to penetrate to the center of each piece and soften it up. Definitely much longer than you'll spend mixing and cooking a standard wheat flour recipe (it takes more water, too) so if you don't plan for that you end up with a gritty cake. Not horrible, but not great, and certainly not a texture I'd use for a birthday cake if I could avoid it. With some extra time and a blender, I did.</p>

<p>Grit-free, gluten free chocolate cake</p>

<p>2C Rice flour<br />
1/2 C Sorghum Flour<br />
1/2 C Potato starch<br />
3 oz Chocolate<br />
1C Cocoa<br />
2C Sugar<br />
1t salt<br />
4t baking soda<br />
1 1/2t xanthan gum<br />
2/3 C flavorless oil<br />
2T Vinegar (optional, but not bad)<br />
1T Vanilla<br />
2 eggs<br />
2C water</p>

<p>Get the water warm but not hot to the touch -- a couple of minutes in the microwave is fine. (You're not cooking the rice, just taking advantage of the fact that warm water works better than cool for hydrating) Stir in the rice flour and the sorghum. It'll make a bit of a paste, but that's fine. Make sure all the flour's wet -- you don't want pockets of dry flour. Cover and let stand at room temperature for an hour, at least. (Longer is fine) If you want to stir it every half hour or so that's fine but not necessary.</p>

<p>After your hour's up, heat the oven to 350F. (And check! A cheap oven thermometer's probably cheaper than a bag of the rice flour, certainly a damn sight cheaper than the xanthan gum. Use it, because your oven dial lies!)</p>

<p>Line two 9" round cake pans with parchment paper. (No other pan treatment is needed, and don't grease and flour anything -- just the parchment, and it really doesn't even need to be all that exact a fit)</p>

<p>Dump the rice and sorghum mix into your blender. Blend (lid on, since cleaning the ceiling's a pain) for a minute or two. Add in the eggs, vanilla, vinegar, oil, and salt. Blend at least until mixed. Your batter will still be a little grainy, but that's okay, it'll cook out. Blend longer if you feel like it, the extra air helps make the cake fluffier.</p>

<p>Break the chocolate up into smallish pieces and melt. (probably a minute or two in the microwave -- do it in 20 second chunks, stirring between each nuking) The chocolate doesn't have to be hot, just liquid, so don't go overboard.</p>

<p>With the blender running, add in the chocolate. (That's what the little hole in the center that the cap's in is for, and why the cap comes out) Whiz it up until it's blended.</p>

<p>Now, if you've got a heavy duty blender (I don't) you can add the rest of the ingredients and whiz together in the blender. Otherwise dump everything into a mixing bowl and mix.</p>

<p>The batter will be a bit rubbery, so plop it into the pans and spread until everything's basically level.</p>

<p>Bake for 30 minutes, or until a toothpick stuck in the center comes out clean. (If 30 minutes isn't enough then check every 5 minutes until they're done) Let 'em cool, then de-pan, frost, and eat.<br />
</p>]]>
      
    </content>
  </entry>
  <entry>
    <title>Dairy-free chocolate buttercream</title>
    <link rel="alternate" type="text/html" href="http://www.sidhe.org/~dan/blog/archives/000471.html" />
    <modified>2009-05-21T00:54:17Z</modified>
    <issued>2009-05-20T20:54:17-05:00</issued>
    <id>tag:www.sidhe.org,2009:/~dan/blog//1.471</id>
    <created>2009-05-21T00:54:17Z</created>
    <summary type="text/plain">I made this as the frosting for a cake I made recently for a friend who can&apos;t do gluten or cow dairy. It&apos;s a pretty straightforward no-egg, no-cook buttercream. The goat butter, interestingly enough, has a really light flavor that doesn&apos;t actually taste at all of goat. If it wasn&apos;t so damn expensive ($5.99 for 8 ounces at the local store) I&apos;d use it for all my buttercream. It&apos;s also nearly white, something cow butter from the supermarket isn&apos;t. Close enough that I think you could reasonably do white buttercream. (Which I don&apos;t, as it means either lots of titanium...</summary>
    <author>
      <name>Dan</name>
      <url>http://www.sidhe.org/~dan/blog/</url>
      <email>dan@sidhe.org</email>
    </author>
    
    <content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.sidhe.org/~dan/blog/">
      <![CDATA[<p>I made this as the frosting for a cake I made recently for a friend who can't do gluten or cow dairy. It's a pretty straightforward no-egg, no-cook buttercream. The goat butter, interestingly enough, has a really light flavor that doesn't actually taste at all of goat. If it wasn't so damn expensive ($5.99 for 8 ounces at the local store) I'd use it for all my buttercream.</p>

<p>It's also nearly white, something cow butter from the supermarket isn't. Close enough that I think you could reasonably do white buttercream. (Which I don't, as it means either lots of titanium dioxide or crisco. Either way, ewww)</p>

<p><br />
8 oz goat butter<br />
4C powdered sugar<br />
3 oz chocolate, melted and cooled<br />
1T vanilla<br />
3-4T liquid (water or milk of some sort)</p>

<p>Melt the chocolate and let it cool. It should be liquid, but only barely warm. (Otherwise it'll melt the butter when you add it, which is no good) I find a minute or two in the microwave, in 20 second intervals, works pretty well.</p>

<p>Beat the butter until it's light and fluffy. Beat in the powdered sugar a cup at a time. (Or more, if you like the whole 'exploding cloud' effect) Beat in the vanilla, and the melted chocolate.</p>

<p>The frosting'll be a bit grainy, so add in the liquid a tablespoon at a time until the consistency is what you want it to be. Water works fine, as does milk from any handy mammal. Soy 'milk' or coconut milk work too, though I find they've each got a distinctive flavor they add to the frosting, so check to see if they match what you want.</p>

<p>This is enough frosting for the outside of a 9" cake. If you've got a 10" cake, or want to do between the layers of the cake with it (Why? Use a good jam instead. Raspberry, strawberry, and cranberry all work, and it's easy to cook up a quick fresh batch) then increase the amounts by 50%.</p>]]>
      
    </content>
  </entry>
  <entry>
    <title>Clearing out the cobwebs</title>
    <link rel="alternate" type="text/html" href="http://www.sidhe.org/~dan/blog/archives/000470.html" />
    <modified>2009-05-21T00:52:57Z</modified>
    <issued>2009-05-20T20:52:57-05:00</issued>
    <id>tag:www.sidhe.org,2009:/~dan/blog//1.470</id>
    <created>2009-05-21T00:52:57Z</created>
    <summary type="text/plain">Sheesh, it has been a while, hasn&apos;t it? Well, it&apos;s time to clear out the dust that&apos;s settled and trim back the weeds. Maybe even upgrade the blog software, but I suppose I wouldn&apos;t want to go overboard. For folks following, I wouldn&apos;t expect updates with much frequency (past the next couple of posts) nor much computer talk. I do enough of that at work; it&apos;ll probably mostly be food and the occasional snarky grumble....</summary>
    <author>
      <name>Dan</name>
      <url>http://www.sidhe.org/~dan/blog/</url>
      <email>dan@sidhe.org</email>
    </author>
    
    <content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.sidhe.org/~dan/blog/">
      <![CDATA[<p>Sheesh, it has been a while, hasn't it? Well, it's time to clear out the dust that's settled and trim back the weeds. Maybe even upgrade the blog software, but I suppose I wouldn't want to go overboard.</p>

<p>For folks following, I wouldn't expect updates with much frequency (past the next couple of posts) nor much computer talk. I do enough of that at work; it'll probably mostly be food and the occasional snarky grumble.</p>]]>
      
    </content>
  </entry>
  <entry>
    <title>Configuration data</title>
    <link rel="alternate" type="text/html" href="http://www.sidhe.org/~dan/blog/archives/000469.html" />
    <modified>2007-11-15T23:57:49Z</modified>
    <issued>2007-11-15T18:57:49-05:00</issued>
    <id>tag:www.sidhe.org,2007:/~dan/blog//1.469</id>
    <created>2007-11-15T23:57:49Z</created>
    <summary type="text/plain"> Configuration systems are a collection of data, a tree of rules, and a set of templates. (Which are arguably just funny rules, but it&apos;s convenient to treat template instantiators and rules as separate things) What rules get fired off and when depends in large part on the data. Lets, then, consider the data. For a configure system we probably don&apos;t care much about what type an individual data element is. int, float, boolean, string, whatever -- ultimately these things will get turned to strings and splatted into templates, so adopting a dynamic-language-style morph-on-demand basic data type is a reasonable...</summary>
    <author>
      <name>Dan</name>
      <url>http://www.sidhe.org/~dan/blog/</url>
      <email>dan@sidhe.org</email>
    </author>
    
    <content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.sidhe.org/~dan/blog/">
      <![CDATA[<p>
Configuration systems are a collection of data, a tree of rules, and  a set of templates. (Which are arguably just funny rules, but it's convenient to treat template instantiators and rules as separate things) What rules get fired off and when depends in large part on the data. Lets, then, consider the data.
</p><p>
For a configure system we probably don't care much about what type an individual data element is. int, float, boolean, string, whatever -- ultimately these things will get turned to strings and splatted into templates, so adopting a dynamic-language-style morph-on-demand basic data type is a reasonable thing. So we'll do that.
</p><p>
There are things we <em>do</em> care about aside from the actual value of a data element, things we use to decide what rules need firing off. For example, we care if the element:
</p><ol>
<li>Has been initialized</li>
<li>Has changed</li>
<li>Has a default value</li>
</ol><p>
All of these things are needed to help decide which rules to fire off.
</p><p>
#1 is straightforward enough. If a data element has no value, then we can't use it yet. That means when we're ordering rules to see which we're going to run, we need to run the ones that set the value before we run the ones that use it.
</p><p>
#2 is also straightforward. If a rule depends on X, and X changes, then we probably need to re-run the rule. The exception here being that we don't need to run the rule if the rule doesn't actually do anything we need. For example, if  rule <em>Foo</em> depends on X and provides Y, and we don't need Y, then there's no point in firing the rule off. Assuming we don't allow side-effects. (Which we aren't, but I'll get to that another time) Whether a data element has changed can also be an interesting question -- who decides? Does the solver engine decide, by comparing the old and new values? Or does a rule affirmatively declare that it's returning X and yes, in fact, X should be considered changed? (And what about the cases where it returns X, with a changed value, but says it hasn't changed? We'll get to that another time too)
</p><p>
#3 is somewhat less straightforward. Configure systems generally don't start from nothing when they run -- there's seed data that has adequate but not necessarily optimal values that you can prime the system with. As a for example, you may not know what the <em>best</em> C integer data type to use is, but it's certainly safe to default to "int". The system may probe for a better value, perhaps <em>long</em> or <em>int64</em> or something, but in its probing it can use <em>int</em> until it finds a better answer. Or you may, by default, assume you can't fork (a safe assumption) but you can always come back and probe to see if you can.
</p><p>
The utility here is that you can ship safe defaults, enough to get the system in a state to go find better answers. Sure, maybe you've filled in the defaults with lowest-common-denominator answers from the C89 and ANSI operating system standards, but that's enough to get you in a position to figure out what the actual useful answers are.
</p><p>
Alternately you could mark values loaded up from the default cache as changed, but... maybe not. There are actually cases where you <em>don't</em> want to mark a default value as changed.
</p><p>
Consider, for example, the person who's actually packaging up things for distribution. We've kind of hand-waved up until now on how these 'trivial' shell scripts, batch files, or default config.h (or whatever) headers and such get created, but this is a good time to un-wave the hands. 
</p><p>
The packager <em>could</em> run the build on each OS you want to support and collect up all the results. But... ewww. That means the packager needs to be minimally fluent with each system, and have access to each system, and if you lose access (or lose the person with fluency) you have a system fall off the list. Not good.
</p><p>
On the other hand, the packager has a perfectly fine configuration system handy. If there's also a set of default values for each system (which someone else can build, can be handed down from maintainer to maintainer, or set to something really simple) then the packaging can just load up the defaults, generate files, and then go on to the next system. <em>If</em> you treat the defaults as unchanged then, if your rules are correct, you won't need to actually run any probes and you're good.
</p><p>
When the end building person gets the package they run the generated simple shell scripts which builds the configurator with the defaults, which then loads in the default values, starts probing, and rebuilds itself. Same templates, same rules, the only difference is that the packager doesn't do the probe and rebuild step, since they don't have to. (Or, rather, if they do it's a sign there's a missing default)
</p><p>
None of this is all that interesting, but it's handy to have as a base when looking at the more interesting bits. Which we'll do later.
</p>]]>
      
    </content>
  </entry>
  <entry>
    <title>Choose your (runtime code instantiation) poison</title>
    <link rel="alternate" type="text/html" href="http://www.sidhe.org/~dan/blog/archives/000468.html" />
    <modified>2007-11-08T03:38:54Z</modified>
    <issued>2007-11-07T22:38:54-05:00</issued>
    <id>tag:www.sidhe.org,2007:/~dan/blog//1.468</id>
    <created>2007-11-08T03:38:54Z</created>
    <summary type="text/plain"> Continuing on from the previous post, let&apos;s consider some of the functionality of a configure system. You will, inevitably, want to instantiate some rules at runtime. You don&apos;t really need to do this -- a code generator the release manager runs could generate all the code explicitly from templates -- but let&apos;s be honest; you&apos;re going to want to. You&apos;ll want it for cases where you have a template rule that needs to have a separate instantiation for each file in a directory. You&apos;ll have it because when you&apos;re designing your rule language you&apos;re going to want run a...</summary>
    <author>
      <name>Dan</name>
      <url>http://www.sidhe.org/~dan/blog/</url>
      <email>dan@sidhe.org</email>
    </author>
    
    <content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.sidhe.org/~dan/blog/">
      <![CDATA[<p>
Continuing on from the previous post, let's consider some of the functionality of a configure system. You will, inevitably, want to instantiate some rules at runtime. You don't really <em>need</em> to do this -- a code generator the release manager runs could generate all the code explicitly from templates -- but let's be honest; you're going to want to.
</p><p>
You'll want it for cases where you have a template rule that needs to have a separate instantiation for each file in a directory. You'll have it because when you're designing your rule language you're going to want run a rule for each element in a list or array which means you really need separate instantiations of the rule for each element. You'll have it because it's a shiny thing and programmers just can't resist Teh Shiny. (Admit it, you know that's true)
</p><p>
There are four different ways to handle this.
</p><p>
You could consider each rule as a closure, close over the environment, which includes the current array entry or filename or whatever.
</p><p>
You could have a way to clone an existing rule and make changes at clone time, basically a rule factory.
</p><p>
You could consider embedding the configuration system's compiler in the configuration engine and just treat the code as text, and recompile things on the fly, like perl's string eval.
</p><p>
You could consider a partial compilation system with placeholders, and basically implement Lisp macros to dynamically generate rules on the fly.
</p><p>
Each of the options has its own strengths and weaknesses.
</p><p>
The closure option is the least attractive of the three options. What you're generally closing over -- what the rule depends on, or produces, or the files a template operates on -- is really more metadata than data. And yes, you can close over that, but it feels kind of awkward. Which isn't to say that closing over the environment is a bad thing, even in a functional language with no side effects (which I hadn't mentioned, but there you go), but it's really not the right thing here. The only real upside is that this should work, but since it's hacking an existing concept in a way that's not particularly true to the concept
</p><p>
The rule factory's more interesting. It's a very limited sort of thing, specialized to do one thing and presumably do it reasonably well. That's not bad, if what you want is what it does, and in this case it is. I'm not all that fond of limited solutions like this, though, as they often feel like someone just stopped thinking and made the best of what they had thought about.
</p><p>
The compiler option's a common one, and it definitely has its advantages. The big downside is it means that new rules mean doing text mangling and then compiling the result -- we've got to have the compiler handy, which makes things more complex. Plus this kind of text filtering can be problematic, as we've seen in perl. (Though as we've established, one thing that a configuration processor is going to have to be good at is template processin) On the other hand, having the compiler handy means that you can provide the rule system as text so if something goes wrong the clever end user can fiddle with it to make it right, without penalizing the end user who doesn't want to be clever.
</p><p>
Then there's the lisp macro system, though it's mis-named, or at least deceptive these days since most people think of macros in terms of text, or recorded little action things in a spreadsheet. Basically you manipulate the compiled code, copying, adding and potentially removing chunks of executable as you string it together into a final form. Very much like the rule factory, actually, except without stopping thinking too soon. (The rule factory is, in fact, a subset of the macro system) Creating a new rule is just a matter of copying the code for an old rule and making some judicious substitutions.
</p><p>
Personally, I find I like macro system form best. It <em>doesn't</em> have to be completely exposed in the actual configuration language, merely implemented that way. (Much the same way as compiling Fortran into object code that does all its control flow via CPS -- the fact that the underlying implementation involves continuations is irrelevant (kinda) to the compiled language, which doesn't. It just means you can potentially do Clever Things with less pain)
</p><p>
It also just feels like the right thing to do. If the config system is potentially going to be dynamically generating dozens, or hundreds, of rules on the fly and pitching them at the solver engine, something a bit less haphazard than text substitution and recompilation seems in order.
</p>]]>
      
    </content>
  </entry>
  <entry>
    <title>Configurafication</title>
    <link rel="alternate" type="text/html" href="http://www.sidhe.org/~dan/blog/archives/000467.html" />
    <modified>2007-11-04T21:03:54Z</modified>
    <issued>2007-11-04T16:03:54-05:00</issued>
    <id>tag:www.sidhe.org,2007:/~dan/blog//1.467</id>
    <created>2007-11-04T21:03:54Z</created>
    <summary type="text/plain"> So, on the near-anniversary of the last post, I&apos;ve been thinking about configuration systems. What they are, what they do, and how you make &apos;em work. They&apos;re one of those things most people never think about, or if they do it&apos;s at best as a user. You probably ran the autoconf-generated shell script, or did whatever else the package you installed needed. It did some strange magic, built some files, and you were done. Easy, right? Well, okay, maybe not so much. If you&apos;ve ever poked around inside the guts of an autoconf-generated script you&apos;re probably aware there&apos;s more...</summary>
    <author>
      <name>Dan</name>
      <url>http://www.sidhe.org/~dan/blog/</url>
      <email>dan@sidhe.org</email>
    </author>
    
    <content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.sidhe.org/~dan/blog/">
      <![CDATA[<p>
So, on the near-anniversary of the last post, I've been thinking about configuration systems. What they are, what they do, and how you make 'em work.
</p><p>
They're one of those things most people never think about, or if they do it's at best as a user. You probably ran the autoconf-generated shell script, or did whatever else the package you installed needed. It did some strange magic, built some files, and you were done. Easy, right?
</p><p>
Well, okay, maybe not so much. If you've ever poked around inside the guts of an autoconf-generated script you're probably aware there's more concentrated evil in there than you'll find outside the source for Clippy. It's just nasty.
</p><p>
That's not really a surprise; it is a multi-unix shell script designed to probe the environment of a system it knows so little about it can't even really count on a properly functioning shell. And yeah, I know, it's a lot better than it was, but still... Ewww. Just because the insides are justified (and possibly obligatory) doesn't make it any less Lovecraftian. (So I'm not knocking autoconf, it just scares me. A lot)
</p><p>
As a developer, configuration systems are a pain, for a few reasons. The first is portability -- by their very nature, configuration systems go look for things that aren't on the system you're developing on. (Because if they were you wouldn't need to go look to see what they are) Writing portable code is annoying, because it requires making good assumptions from the beginning, and that's tough. Especially because, if you're at all comfortable with the system you're working with, it means making assumptions that are different than your default ones.
</p><p>
The second big pain with config systems is that it's a hassle to track down bugs, again because it involves systems different than your own. How can you tell that the code you built on your 32-bit x86 linux system doesn't work when configured and run on a 64 bit AIX box with more than 4G of memory if you don't actually <em>have </em>a 64 bit AIX box with more than 4G of memory?
</p><p>
And the big final annoying thing about configuration systems. Like test frameworks, they're probably completely different from the app you're actually writing. That is, there's likely little or no overlap between the mindset needed to do thing you <em>like</em> to do (writing the game or chat client or whatever it is) and the thing you <em>need</em> to do (write the configuration system). Unless you're writing a configuration system, in which case it gets all meta.
</p><p>
Then there's the whole not knowing what you actually need to go look for. Most of the annoyingly quirky things (like the PDP-11's wacky 32-bit integer format, which is neither big nor little endian, but rather middle endian) you had to deal with in the past have thankfully died enough that you don't have to care, but if you've never had to deal with the vagaries of how shared objects are built and work on a half dozen systems you'd never even think to go probe for them.
</p><p>
All of which is why people generally reach for autoconf, and you really can't blame them. But autoconf is evil, and for a complex system it's inadequate as well, since there's a damn sight more than just a makefile and config.h that you need to build up when you're configuring.
</p><p>
So anyway, configuration systems. What the heck are they, anyway?
</p><p>
If you think about it, there are four bits to configuration systems:
</p><ol>
<li>Rules</li>
<li>Probes</li>
<li>Template instantiation</li>
<li>Seed data</li>
</ol><p>
Seed data gives you sane, functional (though possibly only <em>barely</em> functional) defaults. Probes gather information from the environment to override the defaults, rules decide what probes need to be triggered and what values are produced, and instantiated templates are what you end up with. Possibly in an iterative way, since a lot of environment probing involves instantiating templates (that is, little C programs) which are compiled and possibly run.
</p><p>
It's all very dependency based; to instantiate a template you need to have all the input values, which different rules produce, and some template instantiations depend on other instantiations, which depend on yet other instantiations, and so on. Not all that much different than what make does, only with built-in actions (really built in, into the executable, rather than predefined ways to invoke programs) and generic dependencies rather than time-based file dependencies.
</p><p>
Or, if you like, the mutant bastard child of Prolog and Template::Toolkit.
</p><p>
More interestingly, if you're going to build a configuration system, you can actually manage to do so from scratch, with a bare-bones shell script or batch file, a C compiler, and the linker, which is a pleasant change from the past, where you couldn't. What I mean by this is that, if you assume a C89 standard C compiler (which, given that it's been 18 years since that standard was made seems safe), you can manage to get everything you need to probe the environment.
</p><p>
Think about it. What do you need to build our configuration system? You need to read in and parse rules data and templates, you need to do dependency ordering, you need to instantiate templates, you need to spawn off subprocesses to check individual bits and pieces, and you need to read in the results of those probes. That is, you need <code>fopen</code>, <code>fread</code>, <code>fwrite</code>, <code>fclose</code>, <code>system</code>, and a boatload of templates. Everything else is built into the configuration progam.
</p><p>
All of those things are guaranteed in C89. (And yeah, I know, there may be systems that don't handle them all right, but at this point it's pretty safe to assume they all do) Putting the code together so it compiles and links with close to no knowledge of the system is pretty straightforward too. A series of <code>cc</code> commands followed by <code>ld</code> for unix and its like, for Windows you use whatever the most common compiler is, or you use some environment variable to do it (and have a prompt at the beginning of the batch file for the C compiler and linker -- you can be pretty sure that if someone's running a .bat file it's windows, after all)
</p><p>
Yes, that does mean that maybe you're not using the compiler and linker options the user really wants, but that's fine, because once you've built yourself you just go ask and do it again. Or provide a way to set some environment variables or command line parameters if that's your preference. Worst case there is you need to compile everything twice, but you're probably going to do that anyway, since a full-fledged configuration engine needs to be able to do system-specific stuff, which means probes and rebuilding. The good bit about all that is that you don't need anything to configure your configuration system. Which is good, because otherwise you end up chasing your own tail, and that's annoying. (not to mention hell on your back)
</p><p>
And, of course, once the engine is already built, anything <em>else</em> that uses the engine for configuration already has a prebuilt set of values that can be pretty easily filled in to skip most of the probes. (Or you can package the config system with whatever needs it and just build it, since a half dozen or so extra compiles and links aren't going to noticeably increase the length of time it takes to probe the system for settings)
</p><p>
There's more, but this is enough for now.
</p><p>
(This is all Jim Keenan's fault, I should mention that, in case anyone's curious)
</p>]]>
      
    </content>
  </entry>
  <entry>
    <title>The game of life</title>
    <link rel="alternate" type="text/html" href="http://www.sidhe.org/~dan/blog/archives/000466.html" />
    <modified>2006-11-16T12:12:21Z</modified>
    <issued>2006-11-16T07:12:21-05:00</issued>
    <id>tag:www.sidhe.org,2006:/~dan/blog//1.466</id>
    <created>2006-11-16T12:12:21Z</created>
    <summary type="text/plain"> Okay, so, I&apos;m unimaginative, but I like the game of life. It&apos;s nifty, looks cool, captures the attention of people (like, say, me) who&apos;re attracted to shiny things going &quot;Pling!&quot;, and stresses interesting parts of a system. It was one of the first real things we did for Parrot, and for the longest time it was one of the benchmark programs. Who knows, maybe it still is, I dunno. Anyway, I&apos;ve been working on a GOL for Tornado. It works too, which is cool, and it&apos;s a little surreal to do a full generation with no explicit loops in...</summary>
    <author>
      <name>Dan</name>
      <url>http://www.sidhe.org/~dan/blog/</url>
      <email>dan@sidhe.org</email>
    </author>
    <dc:subject>Tornado</dc:subject>
    <content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.sidhe.org/~dan/blog/">
      <![CDATA[<p>
Okay, so, I'm unimaginative, but I like the game of life. It's nifty, looks cool, captures the attention of people (like, say, me) who're attracted to shiny things going "Pling!", and stresses interesting parts of a system. It was one of the first real things we did for Parrot, and for the longest time it was one of the benchmark programs. Who knows, maybe it still is, I dunno.
</p><p>
Anyway, I've been working on a GOL for Tornado. It works too, which is cool, and it's a little surreal to do a full generation with no explicit loops in it anywhere. And, as expected, it's shaken out a number of bugs in Tornado, both in the ops that're used by the program itself, but also in the error handling (which is, alas, pretty close to nonexistent at the moment), the assembler, and most importantly the garbage collector. Or something the GC tickles, at least, as memory usage grows until there isn't any more, and performance grinds to a halt.
</p><p>
It may sound a little strange, but I <em>like</em> programs that kill my VMs, especially if they're small and viciously abusive. Those are the best kind, as they wrap up all sorts of nasty edge cases and stressors in one handy package. Makes debugging easier, makes testing easier, and shakes out lots of bugs in one go so you don't have to spend all that much time writing test cases, which leaves more time for debugging the code.
</p><p>
There's a second handiness here, in that life, if you look at it right, is a vector program. (Hence the being able to write it with no loops) If you play it with a torroidal board, as is traditional, and you have a vector rotation op (which may not be traditional, but is pretty darned simple), it's just a series of vector rotates, adds, and compares. Turns out that a generation takes 34 Tornado ops to run, regardless of the board size. And yeah, 34 lines of code for life isn't all that great, but as assembly goes, not at all bad, really.
</p><p>
This sorted out all sorts of GC issues, some minor flow control issues, an off-by-one error in the assembler, and a variety of bits'n'pieces.
</p><p>
The runtime isn't too bad either, though I can't say as I'm thrilled with it. On my spiffy new MacBook Pro (2GHz Core 2 Duo processor), for 500,000 generations, I get:
</p><p>
10x10: 12 sec
<br />10x20: 16 sec
<br />10x40: 28 sec
<br />10x80: 50 sec
</p><p>
which, honestly, isn't that swell, though you can see that dealing with larger quantities of data scales pretty nicely -- the 12 seconds for a 10x10 board was pretty bad, honestly, but the steps as the board gets larger make it clear that there's a lot of overhead in the 500K generations,  but the overhead doesn't grow linearly with the amount of data.
</p><p>
Still, you might think that 10K generations/sec on a 10x80 board still isn't that great on a 2 GHz processor, and you'd be right. It isn't, and I don't much like it. (Bleah!)
</p><p>
Luckily for me, there's a rabbit and hat handy. Those numbers are with GCC with no optimizations on. With -O3, the time for a 10x80 board drops to 17 seconds, which is a more respectable 29K generations. Still not as nice as I'd like, but definitely better. (This is the place where I question the algorithm I use, as well as considering Duff's Devicing the loops in the vector ops, but I'm putting that off for now, because I want to write a templating preprocessor to do that, so I can do 'em all in one go)
</p><p>
I should be cutting a 0.06 release in the next day or two, time permitting.
</p><p>
<strong>Update</strong>: Now that I go do the math, a 10x80 board has 800 cells, and at 29k gen/sec (okay, 29411.76 gen/sec) that's 23M cells/sec considered. Or about 85 cycles/cell to do the figuring on this beastie. Okay, maybe it's not all that bad, unless I screwed up my numbers.
</p>]]>
      
    </content>
  </entry>
  <entry>
    <title>Tornado 0.05</title>
    <link rel="alternate" type="text/html" href="http://www.sidhe.org/~dan/blog/archives/000462.html" />
    <modified>2006-09-26T23:06:22Z</modified>
    <issued>2006-09-26T19:06:22-05:00</issued>
    <id>tag:www.sidhe.org,2006:/~dan/blog//1.462</id>
    <created>2006-09-26T23:06:22Z</created>
    <summary type="text/plain"> So, I&apos;ve released Tornado 0.05. This release, in addition to a few bug fixes, now properly handles callbacks into the embedding application. The perl module&apos;s been rev&apos;d to handle this as well. This means you can call tornado code from your perl, you can get results back from that tornado code, and you can register perl subs as callbacks for that tornado code. Nifty! There&apos;s one big limitation, which I&apos;m unhappy with. For reasons that annoy me, when waiting on a handle for results, only callbacks posted in the function the handle represents will be processed. I&apos;d hoped to...</summary>
    <author>
      <name>Dan</name>
      <url>http://www.sidhe.org/~dan/blog/</url>
      <email>dan@sidhe.org</email>
    </author>
    <dc:subject>Tornado</dc:subject>
    <content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.sidhe.org/~dan/blog/">
      <![CDATA[<p>
So, I've released <a href="http://www.sidhe.org/~dan/things/tornado-0.05.tar.gz">Tornado 0.05</a>. This release, in addition to a few bug fixes, now properly handles callbacks into the embedding application. The perl module's been rev'd to handle this as well. This means you can call tornado code from your perl, you can get results back from that tornado code, and you can register perl subs as callbacks for that tornado code. Nifty!
</p><p>
There's one big limitation, which I'm unhappy with. For reasons that annoy me, when waiting on a handle for results, only callbacks posted in the function the handle represents will be processed. I'd hoped to have it so that callbacks from any function in that particular instance of Tornado would be processed, but I wasn't thinking clearly and put together a design that required waiting on multiple condition variables simultaneously, which just doesn't work with pthreads.
</p><p>
Of course, now after spending a few hours hacking that out so that each handle was independent, I realized I could have them all coordinate on a single instance-wide condition variable without much trouble. I'd rejected it for performance reasons -- it'd mean all the waiting threads would wake up and have to check to see if their individual wait condition was satisfied -- but on further reflection that was kind of silly, as there's unlikely to be many host threads waiting on the instance mutex at any one time, so the CPU time spent waking them all up and having them go back to sleep just isn't likely to be a big deal.
</p><p>
Anyway, this works, which is cool. Next step is either to get the Windows build working (I need to get Win-specific thread stuff in) or to get the threads-spawning-threads and messaging code in. Not sure which. I think I ought to get win-threads working first, but message-passing and thread-spawning is a lot more interesting.
</p>]]>
      
    </content>
  </entry>
  <entry>
    <title>There&apos;s something just not right about that...</title>
    <link rel="alternate" type="text/html" href="http://www.sidhe.org/~dan/blog/archives/000461.html" />
    <modified>2006-08-29T23:07:59Z</modified>
    <issued>2006-08-29T19:07:59-05:00</issued>
    <id>tag:www.sidhe.org,2006:/~dan/blog//1.461</id>
    <created>2006-08-29T23:07:59Z</created>
    <summary type="text/plain"> I know it&apos;s an act of supreme, if likely wrongheaded, laziness, but rather than trying to figure out how to build libraries on Windows, or get libraries loading via relative paths right on OS X, I just hacked up the makefiles for the perl module and the main tornado distribution to directly reference the objects. That means you get the whole wad just linked into your perl module, and at some point I&apos;ll get library building done in a proper cross-platform way so you can have your .so / .dll / .dylib again. In the mean time, I get...</summary>
    <author>
      <name>Dan</name>
      <url>http://www.sidhe.org/~dan/blog/</url>
      <email>dan@sidhe.org</email>
    </author>
    <dc:subject>Tornado</dc:subject>
    <content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.sidhe.org/~dan/blog/">
      <![CDATA[<p>
I know it's an act of supreme, if likely wrongheaded, laziness, but rather than trying to figure out how to build libraries on Windows, or get libraries loading via relative paths right on OS X, I just hacked up the makefiles for the perl module and the main tornado distribution to directly reference the objects. That means you get the whole wad just linked into your perl module, and at some point I'll get library building done in a proper cross-platform way so you can have your .so / .dll / .dylib again.
</p><p>
In the mean time, I get to leverage perl's wad 'o platform-specific knowledge and just bodge all the objects together into whatever perl needs, and if someone twiddles with a ruby or python version they can do the same thing.
</p><p>
I'd feel guilty, except the module library still weighs in at under 140K. I think I can live with that, 'specially as the library built for Devel::Size is 57K and there's not nearly so much code in it.
</p><p>
Windows still doesn't quite build right, but if all goes well it will in the next day or so. Assuming you've got the same development environment I do (which'd be activestate perl and the .NET 2003 dev kit), and if you don't then I probably ought to make PPMs to go with the source tarball. 'Cause, what the heck, having the perl module makes testing this stuff a lot easier. Yay for dynamism and all.
</p><p>
(No, there's no particularly interesting insights here. This is all grunt work, though I am <em>so</em> looking forward to learning Windows threading model enough to get its thread stuff into Tornado...)
</p>]]>
      
    </content>
  </entry>
  <entry>
    <title>Now with perly goodness</title>
    <link rel="alternate" type="text/html" href="http://www.sidhe.org/~dan/blog/archives/000460.html" />
    <modified>2006-08-28T00:33:13Z</modified>
    <issued>2006-08-27T20:33:13-05:00</issued>
    <id>tag:www.sidhe.org,2006:/~dan/blog//1.460</id>
    <created>2006-08-28T00:33:13Z</created>
    <summary type="text/plain"> Just cut a release of Tornado 0.04 -- http://www.sidhe.org/~dan/things/tornado-0.04.tar.gz. More fixed bugs and whatnot, but the fun new thing now is that the perl module (in the perl subdirectory) builds and tests, and that includes assembling a sample program, invoking it, and getting the results back. This is, I think, a pretty cool thing. Unfortunately there&apos;s still some manual bits, like you have to copy the tornado shared library into the lib/ directory in the perl module&apos;s build directory when you&apos;re building and testing, but that&apos;s only because I&apos;ve forgotten the Weird Magic needed to get MakeMaker to add...</summary>
    <author>
      <name>Dan</name>
      <url>http://www.sidhe.org/~dan/blog/</url>
      <email>dan@sidhe.org</email>
    </author>
    <dc:subject>Tornado</dc:subject>
    <content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.sidhe.org/~dan/blog/">
      <![CDATA[<p>
Just cut a release of Tornado 0.04 -- <a href="http://www.sidhe.org/~dan/things/tornado-0.04.tar.gz">http://www.sidhe.org/~dan/things/tornado-0.04.tar.gz</a>. More fixed bugs and whatnot, but the fun new thing now is that the perl module (in the perl subdirectory) builds and tests, and that includes assembling a sample program, invoking it, and getting the results back. This is, I think, a pretty cool thing.
</p><p>
Unfortunately there's still some manual bits, like you have to copy the tornado shared library into the lib/ directory in the perl module's build directory when you're building and testing, but that's only because I've forgotten the Weird Magic needed to get MakeMaker to add in library paths and so I cheat. It's probably dead-simple, but for now this is easy enough, and I can write test driver programs in perl rather than having to abuse the main.c in the main tornado source directory.  (Which is terribly inflexible)
</p><p>
That does work out, in its own way. Use the flexible language to do flexible things, the fast (I hope) engine to do the fast things, and let the glue code sort out the interfacing. The way things really ought to be, I think.
</p>]]>
      
    </content>
  </entry>
  <entry>
    <title>Template-driven code</title>
    <link rel="alternate" type="text/html" href="http://www.sidhe.org/~dan/blog/archives/000459.html" />
    <modified>2006-08-23T00:12:09Z</modified>
    <issued>2006-08-22T20:12:09-05:00</issued>
    <id>tag:www.sidhe.org,2006:/~dan/blog//1.459</id>
    <created>2006-08-23T00:12:09Z</created>
    <summary type="text/plain"> I should know by now -- whenever I&apos;m facing large masses of mostly-identical code it&apos;s a sign that it&apos;s time to do some templating. I did this in tornado with the opcodes, in large part because I fully planned on having a simple oploop to start with, and more complex oploops later. I also knew I was going to need to yank out opcode info for the assembler and whatnot, so pre-processing the source made a lot of sense. (This was something that we did quite successfully with Parrot) I didn&apos;t do it with the various MMD math ops....</summary>
    <author>
      <name>Dan</name>
      <url>http://www.sidhe.org/~dan/blog/</url>
      <email>dan@sidhe.org</email>
    </author>
    <dc:subject>Musings on VM design</dc:subject>
    <content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.sidhe.org/~dan/blog/">
      <![CDATA[<p>
I should know by now -- whenever I'm facing large masses of mostly-identical code it's a sign that it's time to do some templating.
</p><p>
I did this in tornado with the opcodes, in large part because I fully planned on having a simple oploop to start with, and more complex oploops later. I also knew I was going to need to yank out opcode info for the assembler and whatnot, so pre-processing the source made a lot of sense. (This was something that we did quite successfully with Parrot)
</p><p>
I <em>didn't</em> do it with the various MMD math ops. This is something I'm coming to regret.
</p><p>
Firstly, there's just a whole wad of cut'n'paste code in because of it, and that's always really error prone. Yech for errors. Fixing bugs in the boilerplate is always a pain when it's boiled over, and you <em>know</em> that you always find the bug in the code that's been copied everywhere but miss one or two spots in the cut'n'paste fix.
</p><p>
Second it really sucks when you realize that you want to roll out a functionality change, but you've got a half-zillion places you have to wedge it in because it's in the boilerplate.
</p><p>
Feh. Should'a done it in the first place. Now I have to go back and rip out the guts of math.c and replace it with code that handles shorter vectors on the RHS of an op for looping. And possibly the LHS too, I'm not sure. (There is the question of what you should do -- loop back to the beginning, or pad with zeroes, or just run the length of the shorter vector)
</p><p>
Ah, well, it's only code. No reason to not rip it out and make it better if there's an actual win to doing so, and it'll make the source code smaller too. Smaller is usually more comprehensible, and I like comprehensible.
</p><p>
(I really ought to cut an 0.04 release -- fixed a bug on the train and added in vector/scalar versions of the math ops. Maybe tomorrow)
</p>]]>
      
    </content>
  </entry>
  <entry>
    <title>Release early and often!</title>
    <link rel="alternate" type="text/html" href="http://www.sidhe.org/~dan/blog/archives/000458.html" />
    <modified>2006-08-21T22:44:31Z</modified>
    <issued>2006-08-21T18:44:31-05:00</issued>
    <id>tag:www.sidhe.org,2006:/~dan/blog//1.458</id>
    <created>2006-08-21T22:44:31Z</created>
    <summary type="text/plain"> Yeah, so I blew it. A required file was missing, one I hadn&apos;t added to the repository. Ouch. Anyway, it&apos;s in, and as a bonus there are some (very) minimal docs in the docs/ directory that I&apos;ve cleaned up a little, the README file is mildly useful, and the garbage collector won&apos;t collect up and kill global variables. I regenerated the ops table too, so opcodes will have constant numbers. Not a huge deal, but stability of opcode numbers is nice. I&apos;ll probably toss and redo the table and bump the version number before release, since there&apos;s a lot...</summary>
    <author>
      <name>Dan</name>
      <url>http://www.sidhe.org/~dan/blog/</url>
      <email>dan@sidhe.org</email>
    </author>
    <dc:subject>Tornado</dc:subject>
    <content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.sidhe.org/~dan/blog/">
      <![CDATA[<p>
Yeah, so I blew it. A required file was missing, one I hadn't added to the repository. Ouch.
</p><p>
Anyway, it's in, and as a bonus there are some (very) minimal docs in the docs/ directory that I've cleaned up a little, the README file is mildly useful, and the garbage collector won't collect up and kill global variables. I regenerated the ops table too, so opcodes will have constant numbers. Not a huge deal, but stability of opcode numbers is nice. I'll probably toss and redo the table and bump the version number before release, since there's a lot of crud in there that I think I'll redo when I have time. (Like there are _vv _ss and _sv versions of opcodes, which made sense until I built the MMD system into tornado, and are now mostly just annoying fiddly things)
</p><p>
I probably ought to dig out some subversion plugin or other that'll automatically generate a changes file.
</p><p>
New version at <a href="http://www.sidhe.org/~dan/things/tornado-0.03.tar.gz">http://www.sidhe.org/~dan/things/tornado-0.03.tar.gz</a>. Feel free to have at it, and I think the comments on the blog are even fixed. (A mixed blessing, since that means blogspam again)
</p><p>
(And if you snagged the tarball before 10:30PM Eastern (I think we're GMT -500) re-snag -- it now builds on linux, and I tossed the damn redundant ops and went full MMD for dispatch. We have it, so we might as well use it, and I can add in static analysis later if I want)
</p>]]>
      
    </content>
  </entry>
  <entry>
    <title>Announcing Tornado version 0.01</title>
    <link rel="alternate" type="text/html" href="http://www.sidhe.org/~dan/blog/archives/000457.html" />
    <modified>2006-08-21T03:00:50Z</modified>
    <issued>2006-08-20T23:00:50-05:00</issued>
    <id>tag:www.sidhe.org,2006:/~dan/blog//1.457</id>
    <created>2006-08-21T03:00:50Z</created>
    <summary type="text/plain"> So, I added in rudimentary garbage collection to Tornado. Nothing fancy, but enough to clean up after itself as its running. (Not as it exits yet, though -- still leaks then) It only builds as packaged on OS X, and requires perl (but, then, if you&apos;re on OS X you have perl) and the docs are abysmal to non-existant, but if you want to play it&apos;s at http://www.sidhe.org/~dan/things/tornado-0.01.tar.gz. It&apos;s under the BSD license, so it&apos;s pretty much a go for it, good luck sort of deal. It ought to work on Linux if someone kicks the config system a...</summary>
    <author>
      <name>Dan</name>
      <url>http://www.sidhe.org/~dan/blog/</url>
      <email>dan@sidhe.org</email>
    </author>
    <dc:subject>Tornado</dc:subject>
    <content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.sidhe.org/~dan/blog/">
      <![CDATA[<p>
So, I added in rudimentary garbage collection to Tornado. Nothing fancy, but enough to clean up after itself as its running. (Not as it exits yet, though -- still leaks then)
</p><p>
It only builds as packaged on OS X, and requires perl (but, then, if you're on OS X you <em>have</em> perl) and the docs are abysmal to non-existant, but if you want to play it's at <a href="http://www.sidhe.org/~dan/things/tornado-0.01.tar.gz">http://www.sidhe.org/~dan/things/tornado-0.01.tar.gz</a>. It's under the BSD license, so it's pretty much a go for it, good luck sort of deal.
</p><p>
It ought to work on Linux if someone kicks the config system a little. I'm working next on getting it to build on Windows, and that should be interesting only because the threading's so different there.
</p><p>
Don't expect much threading, though. This is, right now, entirely vector oriented, with the sole exception that calling into the interpreter to execute a function spawns off a thread and that function runs in the background. The cool tornado threading stuff comes next, but one thing at a time. Good chunks of vector functionality are still missing, and It's also not too friendly to program in either, but <em>that's</em> OK too. It does enough for me to hang more stuff onto it, and I'm fine with that.
</p><p>
If you play with it, expect to make friends with gdb, though. :)
</p><p>
And before anyone decides to mention it, yes, it does have a big function pointer table and do indirect function calls for opcode dispatch. There's enough indirection in place to fix that later, but opcode dispatch time is, bluntly, noise for Tornado right now if it's operating on any real data. Adding together two 100K element vectors (which can be done with a single op) eats more time in memory wait time than all the opcode dispatch  overhead in your entire program.
</p><p>
This may change as the threading ops get added in and I start doing more work with threads rather than vector data, but then I go and massage the opcode function code generator to emit a switch statement or computed goto core or something. Or bite the bullet and write a JIT. Something like that.
</p>]]>
      
    </content>
  </entry>
  <entry>
    <title>Holy cow, it works!</title>
    <link rel="alternate" type="text/html" href="http://www.sidhe.org/~dan/blog/archives/000456.html" />
    <modified>2006-08-14T00:06:51Z</modified>
    <issued>2006-08-13T20:06:51-05:00</issued>
    <id>tag:www.sidhe.org,2006:/~dan/blog//1.456</id>
    <created>2006-08-14T00:06:51Z</created>
    <summary type="text/plain"> Yeah, yeah, I know, it&apos;s been ages. That&apos;s OK, that&apos;s what RSS feeds are for -- to remind you that those of us who&apos;ve gone missing have occasionally resurfaced. Anyway, in my Copious Free Time (which is to say barely ever) I&apos;ve been abusing Tornado, trying to get the basics of the thing to work. And... now it does. Woo! I&apos;ll grant, that&apos;s the sort of Woo! that comes from spending an order of magnitude more time on a dead-simple problem than the problem actually warrants (which means, of course, I was doing threads work) but I don&apos;t care....</summary>
    <author>
      <name>Dan</name>
      <url>http://www.sidhe.org/~dan/blog/</url>
      <email>dan@sidhe.org</email>
    </author>
    <dc:subject>Tornado</dc:subject>
    <content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.sidhe.org/~dan/blog/">
      <![CDATA[<p>
Yeah, yeah, I know, it's been ages. That's OK, that's what RSS feeds are for -- to remind you that those of us who've gone missing have occasionally resurfaced.
</p><p>
Anyway, in my Copious Free Time (which is to say barely ever) I've been abusing Tornado, trying to get the basics of the thing to work. And... now it does. Woo! I'll grant, that's the sort of Woo! that comes from spending an order of magnitude more time on a dead-simple problem than the problem actually warrants (which means, of course, I was doing threads work) but I don't care. Woo! it is.
</p><p>
Okay, so Tornado doesn't as yet have garbage collection, and while it has most of the vector ops in there's no internal threading yet (merely external threading; Sending a function request to an instantiated Tornado instance spawns a new thread to run it), and some of the error checking's a bit dodgy. Which means it leaks like a sieve and falls over if you stare at it funny, but it works anyway. Besides, adding a GC's only an hour or two of work, so that's no big deal.
</p><p>
I've gotta admit, it's kind of cool to write a program that does fairly complex work on megabytes of data, when that program's all of twenty or thirty likes of assembly code and has no explicit loops in it.
</p><p>
I think this beastie's nearly ready for a release for folks to fiddle with, if they're so inclined. Or not, that's OK too.
</p><p>
One thing I have noticed that's really odd is that printf and its ilk don't work from inside Tornado on my OS X box. This is not a huge problem (I've made friends with GDB) but it is puzzling. They work fine from the driver program but not inside the engine code that lives in the .dylib. I have no idea why, and in practice it doesn't matter (since the engine can't do any IO itself by definition) but it's weird. I expect there's some odd flag or library I need to link in, or I should've waved the chicken widdershins around my laptop. Something technical like that.
</p><p>
The nice thing is that there's more than just a skeleton in place. Now there's a good chunk of meat on the bones, and a framework that makes it straightforward and pretty easy (courtesy of some of the lessons I learned from getting Parrot up and going) to extend things. This makes me... happy.
</p><p>
Of course, I expect getting this running on Win32 will make me Unhappy again, but that's OK, I can live with that. The code I need's in example form inside the perl 5 sources (and yeah, I know, <em>that</em> is a scary thought). Just gotta handle thread creation and joining, mutex creation, locking, unlocking, and condition waiting/signalling/broadcasting. (Which, I realize, is done a little differently under windows, but I've already abstracted it away a lot, so I'm fine there, I think)
</p>]]>
      
    </content>
  </entry>
  <entry>
    <title>That whole &apos;outside world&apos; thing sounds like a good idea</title>
    <link rel="alternate" type="text/html" href="http://www.sidhe.org/~dan/blog/archives/000455.html" />
    <modified>2006-06-03T20:12:18Z</modified>
    <issued>2006-06-03T16:12:18-05:00</issued>
    <id>tag:www.sidhe.org,2006:/~dan/blog//1.455</id>
    <created>2006-06-03T20:12:18Z</created>
    <summary type="text/plain"> While I don&apos;t know that I&apos;ve explicitly documented it yet, the Tornado engine has no built-in way to do disk IO, network IO, send signals, or otherwise interact with the outside world. This is on top of the engine monitoring memory use, thread creation, and potentially CPU use, with it being able to nuke a thread safely at a moment&apos;s notice. A nice sandbox, as secure and manageable as I can reasonably design in. That&apos;s all great, since it helps provide you with a safe engine, and since we&apos;re really shooting to be able to run untrusted code that...</summary>
    <author>
      <name>Dan</name>
      <url>http://www.sidhe.org/~dan/blog/</url>
      <email>dan@sidhe.org</email>
    </author>
    <dc:subject>Tornado</dc:subject>
    <content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.sidhe.org/~dan/blog/">
      <![CDATA[<p>
While I don't know that I've explicitly documented it yet, the Tornado engine has no built-in way to do disk IO, network IO, send signals, or otherwise interact with the outside world. This is on top of the engine monitoring memory use, thread creation, and potentially CPU use, with it being able to nuke a thread safely at a moment's notice. A nice sandbox, as secure and manageable as I can reasonably design in.
</p><p>
That's all great, since it helps provide you with a safe engine, and since we're really shooting to be able to run untrusted code that we get from someplace we don't entirely trust. Agents and calculation engines and macro programs and whatnot, and it's nice to have some assurance you're not going to have your system compromised because you downloaded and installed the WhizBang Dive Control plugin for the Aerial Deuces flight simulator.
</p><p>
Of course, the bad part about making it impossible to talk to the outside world is that you can't talk to the outside world. Which is, sometimes, a problem. Sometimes getting data at function start and returning data at function exit isn't enough -- you really want to call out into your environment or send back intermediate results. And while that's possible to do this way, you have to have the environment essentially send in seeker threads looking for data to return. (Which is actually kind of a cool concept, if you think about it. Damned awkward to actually write code for, though)
</p><p>
To get around this, Tornado has a mechanism where the environment can register callback functions that threads can invoke to do things. What the callbacks do is up to the environment, so it's a good idea to make sure that your Tornado programs match up with what your environment exports, but since we tag things that need verification we can at least check function signatures for callbacks. This way the code can have some access, and the host environment can regulate that access and enforce any sort of policy it might want. (Rate limiting, destination filtering, or whatever) When in doubt, punt, right?
</p><p>
This does have some issues, of course. The host does have to register and manage things for the engine, but something's gotta do that, so too bad there, especially since in the simple case it doesn't have to actually do much, just proxy the request. That's the simple case.
</p><p>
The complex case is when the host program actually needs to do some work to satisfy the request, and the things that makes that difficult are, of course, threads. Tornado code probably <em>can't</em> just invoke the callback function -- Tornado's heavily threaded and most host programs... aren't. I fully expect one of the common cases is for a single-threaded main program to embed a Tornado engine to do its thing, and even in a multithreaded case you don't generally want to have random threads calling into yourself. (Yes, I know, if you're embedding a threaded engine and providing callbacks you should be careful. But you should floss after every meal and exercise regularly too, and we all know how often people do that)
</p><p>
For that, then, Tornado allows you to note that a callback isn't thread-safe. If you do, Tornado gets mildly clever.
</p><p>
While it's not made clear to the calling program, each Tornado engine instance has a master thread attached to it. When you start an instance the thread is created, and when you make a call to have the engine do something the call's made to that thread, which then dispatches the call. When any thread running under that engine makes a callback, the callback request is routed to that master thread, which then makes the call into the embedding program but... only when the embedding program has said it's ready for the engine to execute its callbacks. 
</p><p>
Basically the embedding program calls a Tornado function that drains the queue of waiting callback functions, so those functions get called from within the context of whatever host thread is draining the queue. (This way the embedding program can do the things that have to be done in a specific thread, like GUI or database calls, from the right thread)
</p><p>
Alternately the embedding program can note that a callback is always safe (because, for example, the embedding program is multithreaded and has properly protected the code), in which case Tornado code will just call them from whatever thread in the engine that happens to need to make it.
</p><p>
How the embedding program waits, and how it manages callbacks, is a matter for another post.
</p>]]>
      
    </content>
  </entry>

</feed>