How to annoy customers looking to spend multiple thousands of dollars

Allow them to complete the entire order process, and then present them with the following screen at the last step. Continue doing this for a few hours.

We're sorry - We are experiencing some technical problem

Clearly you shouldn't run any business critical systems on Dell and certainly don't employ anyone who lists "Dell Website Developer" on their resume.

On Changes

Debian bug 342658 has illustrated some ways to not run an Open Source project.

Firstly, and by far most importantly, keep a detailed change log. An entry like "Support for Blah has been added" is essentially useless, because it doesn't give someone looking in a detailed view of what has happened. The only sane way to do this is to keep a proper ChangeLog following (something like) the GNU ChangeLog format. For an example of how to do this without fail, see the glibc ChangeLog. I can attest that single ChangeLog file has helped chase down more bugs than anything else, including revision histories. Other good examples are gcc, binutils and emacs. If I can't figure out why something changed from that, I can always go back to the person who did the change to find it, or cross reference it with mailing list postings.

Secondly, if you're writing a library then test cases to stop regressions are of fundamental importance. Again glibc gets this right, where fixes to major bugs must be accompanied by a test case. You should be aiming for correctness and portability, and there's just no way to confirm this unless you actually test your library.

Without these two basic facilities, anyone fresh coming into your code is left treading water without anything to hold on to. And since Open Source is all about getting as many eyes as possible on the code, you need to offer people something to grab on to to avoid drowning in your sea of code.

hexdump format strings

More from the "things you'd learn if you read the manual" department, although the manual as currently written is a little esoteric on this feature of hexdump.

$ hexdump -e ' [iterations]/[byte_count] "[format string]" '

As you might guess, this means apply format string to groups of byte_count bytes, iterations times. Format string is like printf.

You can of course chain multiple formats together, or put them in a file. So say you needed to clag some binary data into a C array, a-la firmware for loading into a driver. You could use

$ hexdump -v -e '6/4 "0x%08x, "' -e '"\n"' ./dump

to get something that fits in 80 columns and is almost ready to go.

how to do max and min properly

The canonical definition of max is something like

#define max(a,b) ( ( (a) >= (b) ) ? (a) : (b))

But this raises many issues with types in C. What if you pass in an unsigned int and a signed int all at the same time? Under what circumstances is the comparison valid? What type should be returned?

The kernel gets around this by being tricky

/*
 * min()/max() macros that also do
 * strict type-checking.. See the
 * "unnecessary" pointer comparison.
 */
#define min(x,y) ({ \
        typeof(x) _x = (x);     \
        typeof(y) _y = (y);     \
        (void) (&_x == &_y);            \
        _x < _y ? _x : _y; })

The give you a clue to how this works by talking about the pointer comparison. C99 6.5.9.2 says that for the == comparison

Both operands are pointers to qualified or unqualified version of compatible types

Where compatible types are defined in 6.7.2.1

Two types have compatible type if their types are the same.

There are additional rules, but gcc is right to warn you when you compare pointers of incompatible types. Note that if the inputs are not pointers, but arithmetic types, the C99 standard says that normal arithmetic conversions apply. You can see that the outcome of this is really probably not what you want, but the compiler has no reason to warn you.

Thus the above code makes a warning spew out if you try to compare values of incompatible types. You can try it yourself

$ cat test.c
#include <stdio.h>

int main(void)
{
        int i = -100;
        unsigned int j = 100;

        if (&i == &j);

        if (i < j)
                printf("OK\n");
        if (i > j)
                printf("i is -100, why is that > 100?\n");

        return 0;
}

$ gcc -Wall -o test test.c
test.c: In function 'main':
test.c:8: warning: comparison of distinct pointer types lacks a cast

$ ./test
i is -100, why is that > 100?

Not the most straight forward warning in the world, but sufficient to let you know you're doing something wrong. Note we don't get any warning where the problem really is, except we get a value we don't expect. C certainly can be a very tricky language to get right!

L1 Bookshelf

In this weeks LWN there was a reference to the editors "L1 Bookshelf" -- i.e. what he could grab without moving.

I thought it might be interesting to find out what others had on thier "L1 Bookshelf". Mine consists of

  • A folder labeled "ELF/ABI stuff" with ELF and ABI documentation.
  • A folder labeled "Superpage" with papers about superpages
  • A folder labeled "IA64 Architecture Stuff" with more papers
  • Latex Line by Line - Diller
  • Understanding and Using COFF - Gintaras Gircys
  • Operating Systems Internals and Design Principles - Stallings
  • Algorithms for compiler designed - Kakde
  • Programming with POSIX Threads - Butenhof
  • TCP/IP Illustrated - Stevens
  • ISO/IEC 9899:1999(E) - C99 Standard
  • IA64 Linux Kernel - Design and Implemenation - Mosberger and Eranian
  • Box of Earl Grey Tea
  • Various Linux CDs

Life on the edge with Mercurial

Unless you are one of the core kernel developers, you always communicate your changes via patches posted to mailing lists. However, if your patch is going to take more than ten minutes to write you need to keep up to date with the upstream kernel source, because otherwise you'll end up hopelessly behind. The problem is that you always need to keep your changes on the top, because you need to be easily able to export them as a patch against the upstream tree at any point.

I call this being on the "edge" of kernel development -- there is nobody further out from the middle than you. Generally, I have found git and any of the wrappers quite painful, but thanks to Matt Chapman I gave Mercurial (hg) a go, and it is perfect.

Firstly, clone a new tree

hg clone http://www.kernel.org/hg/linux-2.6/

This tree you will never touch directly; it is a copy of where Linus is at any point in time. Next, clone a working directory where you will be doing your development.

hg clone linux-2.6 linux-2.6-working

Start doing your work on the linux-2.6-working tree; make commits as necessary as you develop major parts of your work.

You will want to tag your first commit to make it easier to create diffs of your work. Use a local tag, because it is only for your reference within the local tree. So after your first commit do

hg tag -l kernel-import

You can then get all your changes against the kernel you have downloaded from with

hg diff kernel-import:tip

Now several hours/days/weeks later you need to update your changes against the latest upstream versions. Firstly, update the upstream tree

cd linux-2.6
hg pull

There shouldn't be any conflicts or issues, because you have not changed anything locally. Now create a new update tree, cloned from the latest upstream version (just as you did when you started).

hg clone linux-2.6 linux-2.6-update

Now pull into the update tree your development tree. This will (should) have the effect of just grabbing all your changesets.

cd linux-2.6-update
hg pull ../linux-2.6-working

Now your project has multiple heads -- one from your old working tree and one from the new tree you are merging into. You will now need to merge the pulled changes into the new update tree. Do this with

hg update -m

Hopefully there won't be any conflicts, but if there are you will have to resolve them. Once done, the final step is to commit your changes into the new tree.

hg commit -m "merge to new linus tree"

Now create a local tag at the start of your changesets by looking at hg log and using hg tag -l kernel-import first-of-your-changesets-revision-number (is there a better way to do this?).

hg tag kernel-import

So your changesets should now be on the the tip of the update tree. So the update tree becomes the new working tree, and you can archive the old working tree. You can export your patches (for sending to lists, etc) with

hg export kernel-import:tip

Now continue your work in the update tree you just created. Commit as much as you like doing all the development you require, at any time you can use the export from the tag you created to get a patch of your work.

Eventually you will need to re-sync with upstream again. At this point repeat the process; make a new update tree and pull your working tree into it. Archive the old working tree and continue development on the new 'update' tree.

NICTA and Qualcomm

As you will soon hopefully be aware, the Embedded Systems and Real Time Operating Systems group (the research group that Gelato@UNSW is embedded in) within National ICT Australia today released news that they are partnering with Qualcomm on some chipset solutions. Many of you will know people like Gernot and the hacker-extrondiare Benno who made this all possible (while I had nothing to do with it at all).

The essence of this announcement is the tiny microkernel L4 with an operating system layer Iguana wrapped around it. On top of this you can run a modified version of Linux, called Wombat.

This is important for a number of reasons. From a technical point of view, memory protection in embedded systems isn't generally a given -- any process can kill another, making things often very hard to debug. Using this operating system stack you get full memory protection. Secondly, it is possible, and work is ongoing, to formally verify the L4 microkernel. This means that it will have been shown, much as in the way of a mathematical proof, that it works. For your embedded system, which might be stuck somewhere that the reset button is very hard to reach, this is a great reassurance. Lastly, having a modified version of Linux available means there are a number of possibilities for you not having to re-write legacy code. You also avoid licensing issues around using something like ucLinux, which are a big concern to many embedded systems players.

From a non-technical point of view, this represents around 10 years of hard work from various people involved in what has been known as the Keg lab, after the tiny room it all started from in the UNSW Electrical Engineering building. It means that people in Australia are doing really interesting systems work and coming up with products that really stand out and customers want (I can't say more, but be sure that the Qualcomm partnership will not be the last). You should be excited, because starting to commercialise research projects is a push in the right direction to becoming a powerhouse of innovation like so many of the famous American universities. And if you have youth on your side, enrol at UNSW, do the various operating systems courses and come and join us on NICTA Level 6 -- the view is great!

Jack Gale - 12 Jazz Duets for Trombone

My copy of Jack Gale's "12 Jazz Duets" arrived yesterday, ordered from Hickeys (who don't seem to let me link directly to a product). I believe this book is also available for trumpet and maybe even a few other instruments with the same arrangements transposed. I was pleasantly surprised; I was having so much fun I was up till after midnight with the good old Silent Brass!

It includes 12 Duets with a playalong CD; there are two copies of each track, one with both parts, one on the left and one on the right channel, and another copy with just the backing changes. Gale's playing is impeccable and his phrasing and styling are worth trying to emulate. At the tempos on the CD things get pretty hectic, here is a sample of one of the more straight forward blues. The duets move from blues through to rhythm changes, scatting, bop and post bop lines in a variety of normal keys.

It's a great work out for probably an advanced amateur. I think this is a great stepping stone into working on more advanced lines like you would find in a J.J solo transcription book or similar. Personally I think going in cold with those transcriptions is a bridge too far for most people; he wasn't considered a genius because he stuck with the lines and ideas that the aforementioned advanced amateur can keep up with! However, if you could pull off the juicy bits of this book in a few different keys you would be well an truly on your way to making the next step.