The Fugue Counterpoint by Hans Fugal

27Nov/110

clock_getres() and clock_gettime()

In Linux kernel 2.6.33 at least, when you call clock_getres() you may not be getting the whole story if the kernel was compiled without high-res timers. (CONFIG_HIGH_RES_TIMERS)

clock_getres() returns {0, 999848}, which you might think means clock_gettime() has a resolution of about 1ms. But no, if you call clock_gettime() twice in rapid succession you find that it is far higher resolution than that—I usually get either 698 or 699 nanoseconds as the difference. So is clock_getres() wrong? No, not exactly. It is reporting the jiffy that limits clock_settime() and the timers. If you time clock_nanosleep() you find that even if you ask to sleep for 1ns you will sleep until the next jiffy boundary, i.e. as much as 1ms and about 0.5ms on average.

If you look at /proc/timer_list on this machine, it reports a tick resolution of 999848, but hrtimer functions are being used underneath the covers:


active timers:
#0: , hrtimer_wakeup, S:01, hrtimer_start_range_ns, smc_proxy/14652
# expires at 1322421490000000000-1322421490000050000 nsecs [in 1303778479239642688 to 1303778479239692688 nsecs]
clock 1:
.base: ffff88002820e680
.index: 1
.resolution: 999848 nsecs
.get_time: ktime_get

My guess is that clock_gettime() is using HRT and giving high-resolution answers even though you didn't enable using HRT for POSIX timer functions by leaving CONFIG_HIGH_RES_TIMERS unset.

A side effect of this silly situation is that gettimeofday() is also accurate (to µs), though usleep() and nanosleep(), like clock_nanosleep(), are limited to 1ms ticks.

7Jan/110

On TODO lists

Lately in my TODO usage, a pattern has emerged. It's actually rather helpful, and it's dead simple.

I just keep a text file; one for work, one for my dissertation, and one for personal stuff. It's free-form, but roughly divided into 3 sections. First the page table, then the core, and finally the metadata. Yes, I really just pretended my TODO list is a virtual memory system.

In English, the first part is a refresher/jump starter. It's just a list of what's next: what I hope to accomplish today or this week. The hardest part is always starting the next task, and I find it immensely helpful to do the prioritizing once in the morning or perhaps the beginning of the week, and then I can refer to a short and ordered list of things I plan to do, and no effort is wasted hem-hawing about what to do next. (Often, life is interrupt-driven and I don't actually get to what's on my list.)

Then I have the actual list of all the things I need to do, categorized however is useful for that particular file. For work, I have sections of the various task priorities (unbreak now, hi-pri, mid-pri, low-pri), and also groupings by project (most low-pri stuff makes more sense grouped by project because it's usually done opportunistically and/or when I feel like working on that project.) Most of the tasks of any substance actually have tasks in our task tracking thing for collaboration, and most of the details are there. These are just one-line reminders. For my dissertation, it's a more traditional list and an outline of what still needs writing. A little structure but no rules.

Finally, the "metadata" is just notes and free-form text that is relevant to the TODO list but not an actual list itself. Totally free-form.

It's been working well for me, it's surprisingly effective. Together with my notebook where I regularly write out my thoughts as a sort of log to get my juices flowing (especially when I'm feeling stuck), it's a great low(ish) tech solution to staying on top of things and avoiding that overwhelming panic feeling when you can't figure out what to do next, or worse can't remember everything you have to do.

4Jan/110

Thunderbird new message badge

Even as I am trying to get back on top of my email backlog, I find a more effective way to ignore emails and just get work done. The cycle of life, eh?

Those little red badges are annoyingly effective at getting me to drop what I'm doing and check out what's new. When the number is in the hundreds, I can't be bothered to remember what the last count was and so I don't know whether there's new mail, so I'm too frequently opening it to see what's new and whether it needs immediate action. In Thunderbird 2 on OS X, you could configure the new message badge to only show messages new since the last time you looked, not unread messages. Then, if there is a little red circle you know there is new mail that needs attention, and if not there is nothing new. Much more productive.

Initially in Thunderbird 3, this feature was removed by haughty but well-meaning developers who couldn't fathom why anyone would want to see anything but the number of unread messages. There was a beta user hissy fit (I participated), the usual stubborn standoff, a patch, and a whole bunch of inaction. I gave up and went on with my life. Apparently, sometime in the interim reason prevailed and it's back in Thunderbird 3.1. The preference is mail.biff.use_new_count_in_mac_dock.

28Dec/101

Asynchronous Kindle Transfer

I got a Kindle for Christmas, and it's pretty cool. Project Gutenberg never looked so nice. Getting ebooks onto it is pretty simple, just drag and drop. But that only works when the Kindle is plugged in, and I know I will think to download a book usually when the Kindle is not plugged in. Then I have to dig through my downloads folder (which makes a teenager's room look tidy) and find the ebook(s) and drag onto the Kindle. This needs to be automated.

It's actually pretty simple. First, make a "staging" folder. I put mine at ~/Desktop/Kindle. Then, fire up Automator and create a new "Folder Action". Choose /Volumes: whenever anything is added to /Volumes (e.g. when mounting a drive like the Kindle) it will execute. Add the action "Run a Shell Script". Here is my script:

src=$HOME/Desktop/Kindle
dst=/Volumes/Kindle

cd "$src"
while read item; do
  if [ "$item" = "$dst" ]; then
    rsync -av --remove-source-files "$src"/ "$dst"/ | logger -t Kindle
  fi
done

The --remove-source-files option to rsync makes this essentially a recursive move operation. So your staging folder will be empty once it has successfully synced—if you want to keep an off-Kindle backup of your ebooks you won't keep them in the staging folder. (You could omit --remove-source-files, but then if you deleted a book from your kindle it would just be put back the next time you plugged it in which would be annoying.)

The staging folder has the same directory structure as the Kindle, so put the documents you want to copy over into ~/Desktop/Kindle/documents/.

26Oct/100

Mutually-recursive Nested Functions in D

From http://digitalmars.com/d/2.0/function.html:

Unlike module level declarations, declarations within function scope are processed in order. This means that two nested functions cannot mutually call each other:

void test()
{
    void foo() { bar(); }	// error, bar not defined
    void bar() { foo(); }	// ok
}

The solution is to use a delegate:

void test()
{
    void delegate() fp;
    void foo() { fp(); }
    void bar() { foo(); }
    fp = &bar;
}

Future directions: This restriction may be removed.

You can also do away with the useless name, e.g.

void test()
{
    void delegate() bar;
    void foo() { bar(); }
    bar = delegate void() { foo(); };
}
6Oct/100

Git shutup already

So you have a bunch of local files you don't want to check in and you also don't want to add to the project's official .gitignore file(s)? Solution: edit .git/info/exclude. I like to make a symlink e.g. "ln -s .git/info/exclude .gitignore.local".

Thanks GitHub. http://help.github.com/git-ignore/

16Aug/100

Erin’s Whole Wheat Sandwich Bread

My adorable wife is very picky about her bread. It has to be 100% whole wheat, and the right shape for sandwiches. I'm kinda picky too, it has to taste good, have a light and soft crumb, be fun to make, and be able to wrap around my work schedule.

It's easy to make bread that satisfies some of those constraints, but it's been a long process to get everything just right. But get it right I have, and now I'm blogging it.

First, the recipe:

20 oz whole wheat flour
10 g salt

8 oz milk
7 oz water
2 oz sourdough culture
tablespoon honey
tablespoon oil or butter

Mix
Proof covered for an hour
Stretch and fold twice
Proof covered for another hour or two, until it begins to rise
Retard in the fridge overnight or up to a couple days
Stretch and fold, let rest 10 minutes
Shape (8½"x4½" pan) and let rise about 4–8 hours (depending on temperature and culture)
Bake at 375°F to an internal temperature of about 200° (adjust for altitude)

This is 75% hydration—the dough should be soft and sticky when first mixed. I could explain in detail what each of these loaded terms means (e.g. stretch and fold), but most of you are sick of hearing me prattle on about them and the rest of you can ask in the comments or search the all-knowing internet. There are helpful videos for S&F and shaping. Google for the poke test if you're not sure how to know when it's done rising.

It's sourdough, but it's not sour. It does have excellent flavor, but if you are put off by really sour bread don't worry (and if you want it, this isn't the recipe for you). It's not as light as white bread, but it is soft and not dense as whole wheat bread notoriously can be.

WARNING: Science Content!

The 8½x4½ pan size is nominally a "1 lb loaf" pan. This either means 1 lb of dough, or 1 lb of cooked bread (which means roughly 3 oz more than 1 lb of dough). Both are a far cry from the 2+ lb of dough we use here. I don't have a good explanation for this, and it makes me kind of uneasy. But this is the amount of dough it takes to get the loft my wife wants with whole wheat. Probably less would be required for white bread; the fact is whole wheat just doesn't rise as high as white bread—but don't ever let anyone tell you it must be dense or won't rise to lofty heights. Another factor is probably that my wife really likes a high mushrooming crown, and I get the impression that the professional bakers calling this pan a 1 lb loaf pan are satisfied with a squarish top loaf that crowns not far above the top of the pan. Maybe? Please enlighten me.

We grind our own flour, from white wheat. Red wheat and store bought is of course fine, it's a matter of preference. You may adjust the liquid as needed but 75% is going to be a good start for any whole wheat dough. The long life of the dough (thanks to the overnight retard and sourdough pace) gives the enzymes plenty of time to work, which gives a much more interesting and sweeter taste vs the harsh bitter whole wheat taste we all love to hate. You really will be surprised at how good it tastes.

One of the keys to whole wheat bread is to make sure it's kneaded well enough to develop the gluten. The long rise and wet dough means we don't have to do much work to achieve that (no-knead style), but if you want to throw it in your mixer and do the windowpane test, I doubt it would hurt anything.

The short initial rise (2 hours is a short time for sourdough) gets the sourdough beasties going without getting them into overdrive. It takes the dough a little while to cool to retarding temperatures once you stick it in the fridge, and so we will be well into the exponential phase. This means optimal growth after deflating and shaping (once the dough has warmed up again) which is important for good loft in sourdough. You can toy with the timing a bit, e.g. more initial proof for a shorter second proof (up to a point), or a shorter initial proof for a longer second proof (e.g. so it can proof overnight for a first-thing-in-the-morning bake). Exact timings are highly dependent on your ambient temperature and sourdough culture character.

I have a nice sourdough rhythm that I use for maintaining my start. When I use it, e.g. mix up a loaf of bread, I feed the jar 2 tablespoons of flour and water, then let it grow at room temperature about 8–12 hours. Then I feed it again and stick it in the fridge. This way it's ready to go in a few days and is live and healthy in the fridge, not old and dying. But it doesn't spend all its growing time at fridge temperatures, because every other feeding is on the counter, which is important for maintaining various desirable properties. I use the start straight out of the fridge, but you can also refresh the culture 6–8 hours before mixing your bread for extra vigor.

If you have any questions, please ask them and I'll fill in the gaps.

6Aug/100

OSX ignores ownership on external drives by default.

I had reason to copy my harddrive off and back (to reformat as case-sensitive), and I missed one very important detail.

http://www.egg-tech.com/mac_backup/

IMPORTANT STEP: disable "Ignore ownership on this volume".

Yeah, with everything owned by user 99, it won't even boot. You can boot into single-user mode and "chown -R root:wheel /" which will at least let it boot, then you can go into Disk Utility and repair permissions (which will actually do something useful and vital in this situation). Then chown -R your home directory. But it's still a mess to clean up, and you lose all that user and group info.

Tagged as: , , , , No Comments
11Jun/100

Lilypond 2.12 in the OSX Terminal

Getting this error?

$ /Applications/LilyPond.app/Contents/Resources/bin/lilypond
dyld: Library not loaded: @executable_path/../lib//libstdc++.6.dylib
  Referenced from: /Applications/LilyPond.app/Contents/Resources/bin/./lilypond
  Reason: image not found
Trace/BPT trap

I don't know why this is screwed up, but I have a workaround:

ln -s /usr/lib/libstdc++.6.dylib /Applications/LilyPond.app/Contents/Resources/lib

While I'm at it, here's my script in ~/bin:

$ cat ~/bin/lilypond
#! /bin/bash
exec /Applications/LilyPond.app/Contents/Resources/bin/$(basename "$0") "$@"

You can symlink it to midi2ly or whatever other executables you want to execute. Or you could add that directory to your path, of course.

18May/102

Mythtv Cleanup

A couple tricks on manually cleaning up the mess if mythtv gets screwed up.

First, go into your recording directory and "rm *.png". This will remove all the preview images. Now page through the list of recordings and they'll all be rebuilt (this step may require some patience). Now look in the directory again (ls) and notice if there are any video files not accompanied by a .png file—if there are then they're orphaned and you can delete them (or move them somewhere where you can watch them by hand later).

Now pull up your recordings in mythweb and sort by size. Any that are 0 bytes, you should delete (no, I don't know a faster way than clicking and confirming each one).

Finally, if mythtv has something in its db that isn't on disk, it can cause trouble when it's trying to autoexpire. So do this in your recording directory:

grep 'should be local' /var/log/mythtv/mythbackend.log | egrep -o "[0-9_]*\.(mpg|nuv)" | xargs touch
Tagged as: 2 Comments