Planet SLUG

description Planet SLUG - http://planet.slug.org.au/
language en
link http://planet.slug.org.au/

James Polley: THC == The Happy Creationist?

http://feedproxy.google.com/~r/zhasper/~3/peA1DQnhJM4/

From My New Year’s Resolution: Be A Proud Creationist:

The second message was even more bizarre. After the excitement of the first message and the realisation that there was only Australian beer left and the sun hadn’t yet set, we were rapt to see the skywriter trace out the word ‘THE’. We gazed on as he added, ‘CREATOR’. Intrigued, we cooed as the pilot scrawled ‘IS’… and waited for the payoff…

‘JESUS‘.

Fuck. I mean, that’s not even biblically accurate, surely! Jesus doesn’t come in until after the Triwizard Tournament! According to Genesis, Yahwehdidit. He was so clever, he managed to create the world twice in two different orders!

See, I lost interest in this even earlier: when I last saw this bit of drivel it had just turned into “The”, and I got bored and went back inside. For a few moments before that, the sky had proudly been advertising “THC”…

(Side note: I found this past via a pingback on Stilgherrian’s post “Telstra, you goddam bloody idiots!” - you’ll have to read both posts to figure out the connection)

Jeremy Visser: Musings on copyright dates

http://jeremy.visser.name/2009/01/03/musings-on-copyright-dates/

In the context of a blog, with lots of posts from different years, how would copyright apply? Would each post on the blog have a separate copyright? Or would the blog have a copyright as a whole? Or is it up to the author how it should work?

Say I added a footer to the bottom of my blog in the year 2005, which reads:

Copyright © 2005 by Jeremy Visser. All rights reserved.

(Please note that the copyright notices in this post are purely for discussion and illustrative purposes, and are not intended to state the true copyrighted nature of any of the content on this website.)

Now, it’s the year 2009, so there seems to be two popular ways to update this kind of line:

  1. Copyright © 2005-2009 by Jeremy Visser. All rights reserved.
  2. Copyright © 2009 by Jeremy Visser. All rights reserved.

So in the latter one, the copyright date is simply bumped up to 2009. Is it legal to arbitrarily bump the copyright expiration date like that without formal renewal?

In Australia, this is not a problem, as copyright expires 70 years after the author’s death — it has nothing to do with the publication date. In which case, it does not make sense to add a year to copyright declarations of Australian works. I think the following would do fine for me:

Copyright © by Jeremy Visser. All rights reserved.

It would then be up to somebody to look up the date of my death to find out if any of my works are in the public domain.

So why do we add dates to copyright notices? In the United States, the case is the same as Australia — copyright expires 70 years after the death of an author.

I could not find any information on how copyright expiration applies to a corporation in Australia (after all, a corporation cannot die), but in the United States, copyright on a work produced by somebody as part of their official duties while working for a corporation expires 95 years after publication or 120 years after creation (whichever is shorter). In this case, adding dates to copyright notices does make sense.

So, it seems to me that the reason we all add dates to our copyright notices is because we are all sheep and simply copy each others’ copyright notices. Ironic, eh?

Mary Gardiner: RAID is not a backup solution, times one million

http://puzzling.org/logs/thoughts/2009/January/3/backup-policies

Via slashdot.org (yes really, I still pull in the headlines, although the miracle of feed readers has allowed me to confirm that yes, Ars Technica is a better read), a site called Journal Space, which hosted weblogs, lost all their data. They only had a RAID setup as backup, that is, a system that mirrors content between two disks and is designed to protect against disk failure. If you've heard of RAID, you hopefully already know that it is not the same as a backup: if software error or an accident or a malicious act deletes data from one disk, the RAID setup faithfully mirrors it to the other disk. If not, imagine that you have two magical whiteboards. One is copied exactly to the other. If one magical whiteboard totally breaks down, excellent, you have a full copy of your meeting notes and doodles on the other. (Note for accuracy, not all RAID configurations produce a full mirror and sometimes the mirror is spread over more than one spare disk. But you get the idea.) However, if someone rubs something off the whiteboard, or falls over while holding a can of solvent and splashes it on the first whiteboard, everything on it is immediately deleted from the other.

Instead, for home machines you want, most likely, an incremental backup, that is, a separate disk/machine with several copies of your data going back in time. Your data as it was an hour ago. Your data as it was a day ago. Your data as it was a month ago. And so on. I have snapshots of my data for every three hours over the last two months. (Sensible backup programs will notice when data is the same across two or more time periods and only store it once, so your backup disk does not need to be so very much larger than your normal disk.)

For business systems you want both: the quick recovery from disk failure that mirroring systems such as RAID offer, and incremental backups. (I don't maintain business grade systems, ask someone else for best practices if you need them. Internally consistent database backups are something you want to pay particular attention to.)

I note this because in November I gave a talk on home backups for Linux at SLUG and there is one other point of interest: do not trust third party providers to have good backups. It is getting increasingly common to have a lot of your most interesting data on someone else's servers: your email on Google's, your blog over at wordpress.com, contact details for all your friends on Facebook, and so on. But your provider can make both their own catastrophically bad decisions, like Journal Space, and have their creditors suddenly sell their hard disks off in a fire sale, as happened to Digital Railroad.

Which is a big problem, because a lot of third party providers do not provide an easy way to get your data ('easy' would be both a documented API accessible from common programming languages and an installable application), and lots don't provide any way at all. (There's also a whole batch of interesting issues to do with your comments or Wall postings or whatever: you don't necessarily have the right to reproduce them and there would be privacy implications when allowing you to back them up and reproduce them on some other side. LiveJournal, for one, solves this problem by not allowing easy backups of comments left on your journal.)

If your email host, blog host, calendar host, documents host or social networking host failed or deleted your account, how would you fare?

Mary Gardiner: New Years' Encouragements

http://puzzling.org/logs/thoughts/2009/January/2/ny-encouragements

From RavenBlack:

New Year's Encouragements. Instead of making pressurey resolutions for yourself, make positive uplifting recommendations for other people. No negativity allowed, and try not to even imply something negative (eg. "eat better" implies you were eating poorly, but "make delicious home-cooked meals at least once a week" is pretty cleanly positive, and "make more delicious home-cooked meals because your cooking is great" is better still.)

Anyone with encouragements of this positive type may contact me via my preferred method or my LiveJournal, if you have access. (I am beginning, finally, to think about allowing comments on puzzling.org directly, but it's not likely to happen very soon.)

You are hereby invited to do this in your own weblog.

Ben Leslie: Debugging embedded code Using GDB and the Skyeye simulator

http://benno.id.au/blog/2009/01/02/using-gdb-with-skyeye

This post is basically a crash course in using gdb to run and debug low-level code. Learning to us a debugger effectively can be much more powerful than ghetto printf() and putc() debugging. I should point out that I am far from a power-gdb user, and am usually much more comfortable with printf() and putc(), so this is very much a beginners guide, written by a newbie. With those caveats in mind, lets get started.

So the first thing to do is to get our target up and running. For this our target will be a virtual device running with Skyeye. When you start up Skyeye and pass it the -d flag, e.g: $ skeye -c config.cfg -d. This will halt the virtual processor and provide an opportunity to attach the debugger. The debugger will be available on a UNIX socket. It defaults to port 12345. Of course a decent JTAG adapter should be able to give you the same type of thing with real hardware.

Now, you run GDB: $ arm-elf-gdb. Once gdb is running you need to attach to the target. To do this we use: (gdb) target remote :12345. Now you can start the code running with (gdb) continue.

Now, just running the code isn’t very useful, you can do that already. If you are debugging you probably want to step through the code. You do this with the step command. You can step through code line at-a-time, or instruction at-a-time. At the earliest stages you probably want to use the si command to step through instruction at-a-time.

To see what you code is doing you probably want to be able to display information. For low-level start up code, being able to inspect the register and memory state is import. You can look at the register using the info registers command, which prints out all the general-purpose registers as well as the program counter and status registers.

For examing memory the x command is invaluable. The examine command takes a memory address as an argument (actually, it can be a general expression that quates to a memory address). The command has some optional arguments. You can choose the number of units to display, the format to display memory in (hex (x), decimal (d), binary (t), character (c), instruction (i), string(s), etc), and also the unit size (byte (b), halfword (h), word (w)). So, for example to display the first five words in memory as hex we can do: (gdb) x /5x 0x0. If we want to see the values of individual bytes as decimal we could do: (gdb) x /20bd 0x0. Another common example is to display the next 5 instructions, which can be done with (gdb) x /5i $pc. The $pc expression returns the value in the pc register.

Poking at bits and bytes and stepping instruction at a time is great for low-level code, but gdb can end up being a lot more useful if it knows a little bit more about the source code you are debugging. If you have compiled the source code with the -g option, your ELF file should have the debugging information you need embedded in it. You can let gdb know about this file by using the (gdb) symbol program.elf. Now that you actually have symbols and debugging information, you can do things like normal then step command, and it will step through lines of source code (rather than instructions).

The other nice thing you have is that you can easily set breakpoint and watchpoints. (You don’t have to have source debugging enabled for this, but it makes things a lot easier!). Seting a breakpoint is easy, you can set it on a line e.g: (gdb) break file.c:37, or on a particular function e.g: (gdb) break schedule. Breakpoints are neat, but watchpoints are even cooler, since you can test for a specific conditions e.g: (gdb) watch mask 2000.

Now that you have these nice watchpoints and breakpoints, you probably find that most of the time, you just end up printing out some variables each time you hit the point. To avoid this repetitive typing you can use the display command. Each expression you install with the display command will be printed each time program execution stops (e.g: you hit a break-point or watch-point). This avoids a lot of tedious typing!

So, this is of course just scratching the surface. One final thing to consider that will likely make your time using gdb more useful and less painful (i.e: less repetitive typing), is the define command which lets you create simple little command scripts. The other is that when you start gdb you can pass a command script with the -x. So, you might want to consider, instead of littering your code with printf() statements everywhere you might want to write some gdb commands that enable a breakpoint and display some the relevant data.

Good luck, and happy debugging!

Ben Leslie: The trouble with literal pools

http://benno.id.au/blog/2009/01/02/literal-pools

Yesterday we saw how with some careful programming, and the right compiler flags we could get GCC to generate optimally small code for our particular function. In this post we take a look at one of the ways in which GCC fails to produce optimal code. Now there are actually many ways, but the I want to concentrate on in this post is the use of literal pools.

So, what is a literal pool? I’m glad you asked. The literal pool is an area of memory (in the text segment), which is used to store constants. These constants could be plain numerical constants, but their main use is to store the address of variables in the system. These addresses are needed because the ARM instruction does not have any instructions for directly loading (or storing) an address in memory. Instead ldr and str can only store at a ±12-bit offset from a register. Now there are lots of ways you could generate code with this restriction, for example, you could ensure your data section is less than 8KiB in size, and reserve a register to be used as a base for all data lookups. But such approach only works if you have a limited data section size. The standard approach that is taken is that when a variable is used its address is written out into a literal pool. The compiler then generates two instructions, first to read the address from this literal pool, and the second is the instruction to access the variable.

So, how exactly does this literal pool work? Well, so that a special register is not needed to point at the literal pool, the compiler uses the program counter (PC) register as the base register. The generated codes looks something like: ldr r3, [pc, #28]. That codes loads a value at a 28-byte offset from the current value of PC into the register r3. r3 then contains the address of the variable we want to access, and can be used like: ldr r1, [r3, #0], which loads the value of the variable (rather than the address) into r1. Now, as the PC is used as the base for the literal pool access, it should be clear that the literal pool is stored close enough to the code that needs to use it.

To ensure that the literal pool is close enough to the code using it, the compiler stores a literal pool at the end of each function. This approach works pretty well (unless you have a 4KiB+ function, which would be silly anyway), but can be a bit of a waste.

To illustrate the problem, consider this (contrived) example code:

static unsigned int value;

unsigned int
get_value(void)
{
    return value;
}

void
set_value(unsigned int x)
{
    value = x;
}

Now, while this example is contrived, the pattern involved exhibits itself in a lot of real-world code. You have some private data in a compilation unit (value), and then you have a set of accessor (get_value) and mutator (set_value) functions that operate on the private data. Usually the functions would be more complex than in our example, and usually there would be more than two. So lets have a look at the generated code:

00000000 <get_value>:
get_value():
   0:	4b01      	ldr	r3, [pc, #4]	(8 <get_value+0x8>)
   2:	6818      	ldr	r0, [r3, #0]
   4:	4770      	bx	lr
   6:	46c0      	nop			(mov r8, r8)
   8:	00000000 	.word	0x00000000
			8: R_ARM_ABS32	.bss

0000000c <set_value>:
set_value():
   c:	4b01      	ldr	r3, [pc, #4]	(14 <set_value+0x8>)
   e:	6018      	str	r0, [r3, #0]
  10:	4770      	bx	lr
  12:	46c0      	nop			(mov r8, r8)
  14:	00000000 	.word	0x00000000
			14: R_ARM_ABS32	.bss

You can see that each function has a literal pool (at address 0x8 and 0x14). You can also see that there is a relocation associated with each of these addresses (R_ARM_ABS32 .bss). This relocation means that at link time the address of value will be stored at locations 0x8 and 0x14. So, what is the big deal here? Well, there are two problems. First, we have two literal pools containing duplicate data, by storing the address of value twice, we are wasting 4 bytes (remember from yesterday, we have a very tight memory budget and we care where every byte goes). The second problem, is that we need to insert a nop in the code (at address 0x6 and 0x12), because the literal pool must be aligned.

So, how could the compiler be smarter? Well, if instead of generating a literal pool for each individual function it did it for the whole compilation unit, then instead of having lots of little literal pools with duplicated data through-out, we would have a single literal pool for the whole file. As a bonus, you would only need alignment once as well! Obviously if the compilation unit ends up being larger than 4KiB then you have a problem, but in this case you could still save up producing the literal pool until after 4KiB worth of code. As it turns out the commercial compiler from ARM, RVCT, does exactly this. So lets have a look at the code it generates:

00000000 <get_value>:
get_value():
   0:	4802      	ldr	r0, [pc, #8]	(c <set_value+0x6>)
   2:	6800      	ldr	r0, [r0, #0]
   4:	4770      	bx	lr

00000006 <set_value>:
set_value():
   6:	4901      	ldr	r1, [pc, #4]	(c <set_value+0x6>)
   8:	6008      	str	r0, [r1, #0]
   a:	4770      	bx	lr
   c:	00000000 	.word	0x00000000
			c: R_ARM_ABS32	.data$0

You see that the code is more or less the same, but there is just one literal pool right at the end of the file, and no extra nops are needed for alignment. Without merging literal pools we have a .text size of 24 bytes, with the merging we slash that down to 16 bytes.

So merging literal pools is pretty good, but the frustrating thing is that in this example, we don’t even need the literal pool!. If we examine the final compiled image for this program:

Disassembly of section ER_RO:

00008000 <get_value>:
get_value():
    8000:	4802      	ldr	r0, [pc, #8]	(800c <set_value+0x6>)
    8002:	6800      	ldr	r0, [r0, #0]
    8004:	4770      	bx	lr

00008006 <set_value>:
set_value():
    8006:	4901      	ldr	r1, [pc, #4]	(800c <set_value+0x6>)
    8008:	6008      	str	r0, [r1, #0]
    800a:	4770      	bx	lr
    800c:	00008010 	.word	0x00008010
Disassembly of section ER_RW:

00008010 <value>:
    8010:	00000000 	.word	0x00000000

You should notice that the actual location of the value variable is 0x8010. At address 0x800c we have the literal pool storing the address of a variable which is in the very next word! If we optimised this by hand, we would end up with something like (need to verify the offset):

Disassembly of section ER_RO:

00008000 <get_value>:
get_value():
    8000:	4802      	ldr	r0, [pc, #4]	(8008 <set_value+0x8>)
    8002:	4770      	bx	lr

00008004 <set_value>:
set_value():
    8004:	6008      	str	r0, [pc, #0]
    8006:	4770      	bx	lr
Disassembly of section ER_RW:

00008008 <value>:
    8008:	00000000 	.word	0x00000000

If we get rid of the literal pool entirely, we save the memory of the literal pool itself (4 bytes), plus the two instructions need to load values out of the literal pool (4 bytes). This cuts our text size down to a total of only 8 bytes! This is a factor 3 improvement over the GCC generated code. Granted, you are not always going to be able to perform this type of optimisation, but when you care about size, it is quite important. It would be nice if gcc supported a small data section concept so that you could specify variables that essentially resised within the literal pool instead of needing an expensive (in terms of space and time) indirection.

For this project, it looks like the code will have to be hand tweaked assembler, which is frustrating, because when you use a person as your compiler iterations become really expensive, and you want to make sure you get your design right up front.

Dave Airlie: Isabel Airlie.

http://airlied.livejournal.com/64942.html

Isabel was delivered this morning, at 11:54am, at 8lb13oz (4.07kg).

I'll be slow on anything non-baby related for a while :)

James Polley: Shelley the Republican on Ubuntu

http://feedproxy.google.com/~r/zhasper/~3/J_FcqPhNDYk/

People have been telling me to read STR for ages, but I’ve never got around to it. Pascal just went to the site while I was shoulder surfing - and thus I discovered this review of Ubuntu:

One of the great things about Windows is the ease of obtaining powerful utilities and applications. In addition to hundreds of great titles available on CD-ROM you can download awesome shareware applications: simply click on Setup.exe and most installers will instantly deploy your chosen software, sometimes with cool bonus productivity apps that enhance your browsing experience. In comparison with Microsoft’s common-sense approach, pandemonium reigns on the Linux platform.

The only way to install software is via a tool called the ‘package manager’ which is confusingly also called ‘Synaptic’. This works according to a similar principle as a communist super-market: You have a limited range of software which has been chosen on a purely ideological basis rather than functionality. If you want to ‘think different’, it’s tough-luck again: Another obvious fail for the â€˜contender’.

To make matters worse, in order to install an application you must be ‘root’ which entails memorizing a series of confusing passwords. By contrast Windows allows any user to install the applications they need to do their work - a wise productivity gain that endears the flexible NT platform to IT departments the world over.

The rest is good reading too. Very informative! I’m switching away from Ubuntu forthwith.

Martin Visser: A short holiday read - and an insight into me.

http://marty.sunriseroad.net/2009/01/01/a-short-holiday-read-and-an-insight-into-me/

Around 1993 was probably a big turning point in my career life. Up until then I had spent a lot of time involved in designing and implementing solutions around process control systems at the Port Kembla Steelworks. When I graduated (in 1985) I was doing straight electrical control work as well as some PLC (programmable logic control systems work). A few years later I was writing FORTRAN code than allowed operators to control big machines (such as plate mills and cranes). I became fascinated with communications and networking, and started doing work in that front in the late 80’s, a lot of this was around the low-level communications between process control computers, but also more general networking like DECnet. I got introduced into UNIX and C in the early 90’s, both doing some communications driver coding as well as X11 based operator interfaces. I bought my first PC for home in 1993 and made sure it could run Windows 3.1 and Linux (SLS, which later begat Slackware, on around 30 floppies was my first distro). I had BBS access and the ‘net soon enough as well. I guess, just like today, I was always reading about new things, and at least having a bit of a play at making things work.

One thing I had a little play with at the time was VRML, which is a 3D markup language. At work we also started using the Internet tools a lot. Also the new engineering projects were all being done in CAD, some in 3D, with intent on being better able to plan all the services required on such huge mechanical and civil works. I was also a big fan of raytracing, particularly POVray. Anyway, I saw all this coming together, potentially a huge aid to engineering support. I was starting to becoming more focussed on IP, ATM and other network protocols so it probably was almost farewell to process control world.

So I wrote the following short-story in 1993. The chief electrical engineer at the time loved it, and it appeared in the departmental newsletter. I think it was quite well received, though it is probably the first and only short story I have had published. I have made a few small edits from the original, mainly to make it a little clearer to non-steelworkers. I hope you like it!

The VirtEng.
Kurt abruptly woke from his doze as the ‘comm indicated that his attention was required. Despite wanting to throw a heavy object at it, he heeded the ringing.
‘Comm answer...Greber here, who is it?”
“It’s Max, with got a problem at the Finishing Mill again; hyper-axial gamma ray gauge it seems.”. The last thing Kurt wanted to see on the ‘comm screen was Max.
“Strike, can’t I get a moment’s peace, even out here?” He gazed solemnly at the gently swaying palm trees, and the glistening sand out of his window. “OK I’ll get on to it. Bye. ‘Comm hangup.”
Reluctantly, Kurt stepped across his room and donned the VirtEng, and waited for the retinal scan to authorise him.
VirtEng …Goto Port Kembla Finishing Mill” he uttered to the machine. In an instant he felt the familiar experience of floating above this bane of his life. As he pointed his way down, the VirtEng displayed the detail of the 21 stand rolling mill. The physical view of the mill from above always fascinated him despite rather being someplace else. The hundreds of tonnes of metal and motors and hydraulics had to be coordinated to within a micron in microseconds in order to make the steel strip of the correct properties. As he came up level with the end of the mill, his attention was drawn to the pinkish hue of the gamma ray thickness gauge. For years now the VirtEngs had been able to diagnose equipment status, even subtle problems, and give an indicative colour to the components. “Just out of tolerance” he thought as he mused on the problem.
VirtEng … Logical view” he instructed his helmet and the scene before him faded and a conglomeration of blocks and lines appeared. He began walking past the various schematic components of the gauge. Occasionally he would stop at an amplifier or processor and point at the various panels before him. Charts showing the equipment status immediately appeared before him as he pursued a prognosis of the fault. He could also access a history of this component; not just in this gauge, but of course the database was continually fed by input from all the installations in the world. “It must be this proton accumulator” he thought, “I’ll get the Auto-Tric”. After issuing the dispatch, he investigated the software problem that caused the overload. Again each instruction could be removed, visually displaying a history of past values and execution sequences. After tuning a parameter down with a downward wipe of his finger and satisfied with his work, Kurt thought he’d call it a day.
Just after he issued the “VirtEng …Physical view” command he made out the shape of the “Auto-tric” trundling down the mill floor. With a PA-481F in the manipulator, the ‘droid electrician approached the gauge and within a minute had the component replaced and tested. Without as much as a nod the robot returned to the Parts Dispatch Terminal from whence it came. As the mill commenced rolling again, Kurt felt comfortable with the soft blue emanating from the gamma gauge, indicating it’s sound health.
Just as Kurt turned to depart, his virtual image bumped into the virtual image of the Mill Superintendent.
“Thanks for that Kurt, I thought you were on R&R, but I knew you would help us out”.
“Sure, It’s only Fiji, I’ve been there before anyhow.” As the stereo headset filled with sound of metal meeting metal, Kurt issued his “Log out” to the machine and returned to the pleasant scenery and sounds at his window of a few minutes before the call-out. He returned to his couch for another snooze, in readiness for a late afternoon surf. As sleep drifted back, a thought entered his head - “I wonder what people did before VirtHoliday?”

Martin Visser – copyright 1993 - 2009

Ben Leslie: Small code

http://benno.id.au/blog/2009/01/01/space_conserving_code

A project that I’m working on at the moment calls for a very small footprint. This post is about how to make code really small for the ARM architecture.

As you can probably guess, I’m interested in operating system code, so as an example, I’ve taken a very simple piece of operating system code, and stripped it right back to demonstrate some of the techniques to use when optimising for space. So here is the snippet of code we are going to optimise:

01 struct thread {
02     unsigned int notify_bits;
03 };
04 
05 unsigned int
06 poll(struct thread *thread, unsigned int mask)
07 {
08     unsigned int result;
09     result = thread->notify_bits & mask;
10     if (result) {
11         thread->notify_bits &= ~result;
12     }
13     return result;
14 }

In this very simple operating system we have threads (thread data is stored in struct thread). Each thread has a set of 32 signals (encoded in a single word notify_bits). This poll is used by a thread to determine if it has been sent any signals. The mask parameter is the set of signals that the thread is interested in checking. So, a thread can check if a single signal has been thread, or if any signal has been set, or if a specific subset of signals has been set. The function returns the signals that are available (which is simply the bit-wise and of notify_bits and mask). It is important that the function clears any signals that have been returned. This makes sure that if poll is called twice the same signals are not returned. This is achieved in lines 10—12.

So, our goal is to try and get this code as small as possible. And every byte counts! First off, we just try and compile this with the standard ARM gcc compiler. I’m using version 4.2.2. So we start with: $ arm-elf-gcc -c poll.c -o poll.o. We can then use object dump to work out what the compiler did: $ arm-elf-objdump -dl poll.o.

00000000 <poll&ht:
poll():
   0:	e1a0c00d 	mov	ip, sp
   4:	e92dd800 	push	{fp, ip, lr, pc}
   8:	e24cb004 	sub	fp, ip, #4	; 0x4
   c:	e24dd00c 	sub	sp, sp, #12	; 0xc
  10:	e50b0014 	str	r0, [fp, #-20]
  14:	e50b1018 	str	r1, [fp, #-24]
  18:	e51b3014 	ldr	r3, [fp, #-20]
  1c:	e5932000 	ldr	r2, [r3]
  20:	e51b3018 	ldr	r3, [fp, #-24]
  24:	e0023003 	and	r3, r2, r3
  28:	e50b3010 	str	r3, [fp, #-16]
  2c:	e51b3010 	ldr	r3, [fp, #-16]
  30:	e3530000 	cmp	r3, #0	; 0x0
  34:	0a000006 	beq	54 <poll+0x54>
  38:	e51b3014 	ldr	r3, [fp, #-20]
  3c:	e5932000 	ldr	r2, [r3]
  40:	e51b3010 	ldr	r3, [fp, #-16]
  44:	e1e03003 	mvn	r3, r3
  48:	e0022003 	and	r2, r2, r3
  4c:	e51b3014 	ldr	r3, [fp, #-20]
  50:	e5832000 	str	r2, [r3]
  54:	e51b3010 	ldr	r3, [fp, #-16]
  58:	e1a00003 	mov	r0, r3
  5c:	e24bd00c 	sub	sp, fp, #12	; 0xc
  60:	e89da800 	ldm	sp, {fp, sp, pc}

So, our first go gets us 100 bytes of code. Which is 10 bytes (or 2.5 instructions) for each of our lines of code. We should be able to do better. Well, the first thing is we should try is to use optimisation: $ arm-elf-gcc -c poll.c -o poll.o -O2. This gives us a much better code generation output:

00000000 <poll>:
poll():
   0:	e5902000 	ldr	r2, [r0]
   4:	e1a0c000 	mov	ip, r0
   8:	e0110002 	ands	r0, r1, r2
   c:	11e03000 	mvnne	r3, r0
  10:	10033002 	andne	r3, r3, r2
  14:	158c3000 	strne	r3, [ip]
  18:	e12fff1e 	bx	lr

So this got us down to 28 bytes. A factor 4 improvement for one compiler flag, not bad. Now, -O2 does some standard omptimisations, but -Os, will do optimisations specifically for reducing the amount of code. So trying: $ arm-elf-gcc -c poll.c -o poll.o -Os. This gives a little bit better code-gen:

00000000 <poll>:
poll():
   0:	e5903000 	ldr	r3, [r0]
   4:	e1a02000 	mov	r2, r0
   8:	e0110003 	ands	r0, r1, r3
   c:	11c33000 	bicne	r3, r3, r0
  10:	15823000 	strne	r3, [r2]
  14:	e12fff1e 	bx	lr

Down to 24 bytes (6 instructions), is pretty good. Now, as you can see the generated code has 32-bits per instruction. The some of the ARM architectures have two distinct instruction sets, ARM and Thumb. The Thumb instruction set uses 16-bit per instruction, instead of 32-bit. This denser instruction set can enable much smaller code sizes. Of course there is a trade-off here. The functionality of the 16-bit instructions is going to be less than the 32-bit instructions. But lets give it a try. At the same time, we will tell the compiler the exact CPU we want to compile for (which is the ARM7TDMI-S) in our case. The compiler line is: $ arm-elf-gcc -c poll.c -o poll.o -Os -mcpu=arm7tdmi -mthumb. Which produces code like:

00000000 <poll>:
poll():
   0:	6803      	ldr	r3, [r0, #0]
   2:	1c02      	adds	r2, r0, #0
   4:	1c08      	adds	r0, r1, #0
   6:	4018      	ands	r0, r3
   8:	d001      	beq.n	e <poll+0xe>
   a:	4383      	bics	r3, r0
   c:	6013      	str	r3, [r2, #0]
   e:	4770      	bx	lr

So, now we are down to 16 bytes, so in Thumb we need 8 instructions (2 more than ARM), but each is only 2 bytes, not 4, so we end up with a 1/3 improvement. To get any further, we need to start looking at our code again, and see if there are ways of improving the code. Looking at the code again:

00 unsigned int
01 poll(struct thread *thread, unsigned int mask)
02 {
03     unsigned int result;
04     result = thread->notify_bits & mask;
05     if (result) {
06         thread->notify_bits &= ~result;
07     }
08     return result;
09 }

You may notice that the branch instruction on line 5, you may notice that this is actually redundant. If result is zero, then ~result well be 0xffffffff. Given this thread->notify_bits &= 0xffffffff will not change the value of thread->notify_bits. So, we can reduce this to:

00 unsigned int
01 poll(struct thread *thread, unsigned int mask)
02 {
03     unsigned int result;
04     result = thread->notify_bits & mask;
05     thread->notify_bits &= ~result;
06     return result;
07 }

When we compile this we get down to:

00000000 <poll>:
poll():
   0:	6803      	ldr	r3, [r0, #0]
   2:	4019      	ands	r1, r3
   4:	438b      	bics	r3, r1
   6:	6003      	str	r3, [r0, #0]
   8:	1c08      	adds	r0, r1, #0
   a:	4770      	bx	lr

This gets us down to 6 instructions (12 bytes). Pretty good since we started at 100 bytes. Now lets look at the object code in a little bit more detail. If you look at address 0x8, the instruction simply moves register r1 into register r0 so that it in the right place for return. (Note: The ARM ABI has the return value stored in r0). This seems like a bit of a waste, it would be good if there was a way we could have the value stored in r0 and not waste an instruction just moving values between registers. Now, to get a better understanding of what the instructions are doing, I’m going to slightly rewrite the code, and then compile with debugging, so we can see how the generated code matches up with the source code. So first, lets rewrite the code a little bit:

00 unsigned int
01 poll(struct thread *thread, unsigned int mask)
02 {
03     unsigned int tmp_notify_bits = thread->notify_bits;
04     mask &= tmp_notify_bits;
05     tmp_notify_bits &= ~mask;
06     thread->notify_bits = tmp_notify_bits;
07     return mask;
08 }

You should convince yourself that this code is equivalent to the existing code. (The code generated is identical). So, we can now line up the source code with the generated code. On line 03 (unsigned int tmp_notify_bits = thread->notify_bits), this matches up with address 0x0 (ldr r3, [r0, #0]). So, register r3 is used to store variable tmp_notify_bits. The parameter thread is stored in register r0. Now, line 04 (mask &= tmp_notify_bits) matches directly with address 0x2 (ands r1, r3). Register r1 matches directly with the mask parameter. The important part of restructuring the code as we have done, is that it becomes obvious that we can directly using the mask parameter instead of needing an extra variable like in the previous code. As we continue line 05 (tmp_notify_bits &= ~mask), matches directly to 0x4 (bics r3, r1). The bics instruction is quite neat in that it can essentially do the &= ~ in one 16-bit instruction. Line 06 (thread->notify_bits = tmp_notify_bits) stores the result back to memory, matches directly to 0x6. Now the final line of code (return mask;), needs two instructions 0x8 and 0xa (adds r0, r1, #0 and bx lr). Now the reason we need to instructions is because mask is stored in register r1, and the return value needs to be in register r0. So how can we get mask to be stored in r0 all along? Well, if we switch the parameters around poll(unsigned int mask, struct thread *thread), the mask will instead be stored in r0 instead of r1. (Note: We don’t necessarily have to change the interface of the function. If we want to support keep the interface we can use a simple macro to textually swap the parameters.) If we compile this, we get the following generated code:

00000000 <poll>:
poll():
   0:	680b      	ldr	r3, [r1, #0]
   2:	4018      	ands	r0, r3
   4:	4383      	bics	r3, r0
   6:	600b      	str	r3, [r1, #0]
   8:	4770      	bx	lr

So, we have got this down to 5 instructions, 10 bytes. This is a factor 10 improvement, not bad!

So a bit of a review:

James Polley

http://feedproxy.google.com/~r/zhasper/~3/_2m0Wp29kTo/

2009 really started with a bang.  Here’s what James twittered about said bang:
Firemen here to put out the oven fire http://skitch.com/jdumay/97em/kitchenonfire.

Mary Gardiner: 2009 plans

http://puzzling.org/logs/thoughts/2009/January/1/2009-plans

One year I'd like to do the same project Skud is doing for 2009, that is: a resolution a week. But this year is a finishing year for me, not a starting year.

A quick wrap-up on 2008 resolutions:

The first half of 2008 was pretty difficult for me. In retaliation, Andrew and I screamed around the south island of New Zealand in August. I do recommend its recuperative powers.

Major goals for 2009:

Other plans in 2009:

Also, given the PhD submission thing, I will probably be looking for a job towards the end of 2009. I do not know yet if I am going to apply for postdoctoral positions, this will probably depend on achieving a couple of major conference acceptances in 2009. And on deciding whether I want to live in the northern hemisphere. Even if I am I may be looking for programming or similar work in the short-term to wait out my examination process. So, keep in touch, if you want to offer me work, or come to my submission party. Or both.

Michael Fox: Back from little break..

http://blog.heimic.net/2008/12/31/back-from-little-break/

Just got back today from Port Macquarie. It was a 5 hour drive back, which was alright. I figured if we left tomorrow or even in the next few days then the delays would be bad, so we only planned to stay until the 31st and then make an early break.

Traffic was good, as compared to the day we went up. However managed to see 3 radar traps and come by one mobile RBT. Cops were out writing tickets, no doubt about that.

Jeremy Visser: Some logos

http://jeremy.visser.name/2008/12/31/some-logos/

Okay, what do these logos have in common?

They all use stripes, and they’re ugly. Ugly, I tell you. I don’t know why, but I hate logos that use stripes like these. Please, just use gradients, drop shadows, or just go psycho with the gloss.

Erik de Castro Lopo: Parsec and Expression Parsing.

http://www.mega-nerd.com/erikd/Blog/CodeHacking/Haskell/parsec_expression_parsing.html

Haskell's Parsec parsing library (distributed with the GHC compiler since at least version 6.8.2) contains a very powerful expression parsing module Text.ParserCombinators.Parsec.Expr. This module makes it easy to correctly parse arithmetic expressions like the following according to the usual programming language precedence rules.


  2 + a * 4 - b

Once parsed, the abstract syntax tree for that expression should look like this:


hackfest living room

The original Parsec paper by Daan Leijen even gives a small example of using the expression parser. As can be seen below, the operators are defined in a table (ie a list of lists) where the outer list is a set precedence levels (from highest precedence to lowest) and each inner list specifies all the operators for that precedence level.


  module Parser
  where
  
  import Text.ParserCombinators.Parsec
  import Text.ParserCombinators.Parsec.Expr
  
  expr :: Parser Integer
  expr = buildExpressionParser table factor <?> "expression"

  table :: [[ Operator Char st Integer ]]
  table = [
      [ op "*" (*) AssocLeft, op "/" div AssocLeft ],
      [ op "+" (+) AssocLeft, op "-" (-) AssocLeft ]
      ]
    where
      op s f assoc = Infix (do { string s ; return f }) assoc
  
  factor = do { char '(' ; x - expr ; char ')' ; return x }
     <|> number
     <?> "simple expression"
  
  number :: Parser Integer
  number = do { ds <- many1 digit; return (read ds) } <?> "number"

The above simple example works fine but there is a potential for a rather subtle problem if the expression parser is used in conjunction with the Text.ParserCombinators.Parsec.Token module.

The problem arises when trying to parse expressions in C-like languages which have bitwise OR (|) as well as logical OR (||) and where the bitwise operation has higher precedence than the logical. The symptom was that code containing the logical OR would fail because the expression parser was finding two bitwise ORs. After banging my head against this problem for a considerable time, I posted a problem description with a request for clues to the Haskell Cafe mailing list with the following code snippet:


  import qualified Text.ParserCombinators.Parsec.Expr as E

  opTable :: [[ E.Operator Char st Expression ]]
  opTable = [
      -- Operators listed from highest precedence to lowest precedence.

      {- snip, snip -}

      [    binaryOp "&" BinOpBinAnd E.AssocLeft ],
      [    binaryOp "^"  BinOpBinXor E.AssocLeft ],
      [    binaryOp "|"  BinOpBinOr E.AssocLeft ],

      [    binaryOp "&&" BinOpLogAnd E.AssocLeft ],
      [    binaryOp "||" BinOpLogOr E.AssocLeft ]
      ]

  binaryOp :: String -> (SourcePos -> a -> a -> a)
                     -> E.Assoc -> E.Operator Char st a
  binaryOp name con assoc =
      E.Infix (reservedOp name >>
          getPosition >>=
          return . con) assoc

Unfortunately, no real answer was forthcoming and while I still held out hope that an answer might eventuate, I continued to work on the problem.

Eventually, after reasoning about the problem and looking at the source code to the Token module I realised that the problem was with the behaviour of the reservedOp combinator. This combinator was simply matching the given string at the first precedence level it found so that even if the code contained a logical OR (||) the higher precedence bitwise OR would match leaving the second vertical bar character un-parsed.

My first attempt at a solution to this problem was to define my own combinator reservedOpNf using Parsec's notFollowedBy combinator and use that in place of the problematic reservedOp.


  opChar :: String
  opChar = "+-/%*=!<>|&^~"

  reservedOpNf :: String -> CharParser st ()
  reservedOpNf name = try (reservedOp name >> notFollowedBy (oneOf opChar))

This solved the immediate problem of distinguishing between bitwise and logical OR, but I soon ran into another problem parsing expressions like this:


  if (whatever == -1)
     .....

which were failing at the unary minus.

A bit of experimenting suggested that again, the problem was with the behaviour of the reservedOp combinator. In this case it seemed the combinator was matching the given string, consuming any trailing whitespace and then the notFollowedBy was failing on the unary minus.

Once the problem was understood, the solution was easy, replace the reservedOp combinator with the string combinator (which matches the string exactly and doesn't consume trailing whitespace), followed by the notFollowedBy and then finally use the whiteSpace combinator to chew up trailing white space.


    reservedOpNf :: String -> CharParser st ()
    reservedOpNf name =
        try (string name >> notFollowedBy (oneOf opChar) >> whiteSpace)

Despite minor problems like the one above, I am still incredibly impressed with the ease of use and power of Parsec. Over the years I have written numerous parsers, in multiple host languages, using a number of parser generators and I have never before used anything that comes close to matching Haskell and Parsec.

Bruce Badger: New version of Hyper

http://openskills.blogspot.com/2008/12/new-version-of-hyper.html

Hyper is a Smalltalk library available under the LGPL which implements RFC 2616 and friends aka HTTP. You can use Hyper to build a web server or a web client. As an example, you could use Hyper as an HTTP server underneath Seaside (a rather cool website content library).

The new version is 1 340 and can be found in the Cincom public Store repository. This version picks up a number of changes made by Dale Henrichs of GemStone. Thanks Dale!

There are no big changes here, but if you happen to want to run a robust HTTP server for Seaside from within your Gemstone database, then this is the version for you.

Have fun :-)

Dave Airlie: AMD release r600/r700 code

http://airlied.livejournal.com/64691.html

AMD today pushed the initial code to support acceleration on the r600/r700 range of GPUs.

This consists of r6xx-r7xx-support branches in the drm, radeonhd and a new r600_demo repo.

This code is really only for developers at this point but its great to see AMD finally get things lined up to allow this code to be released.

I've only been barely involved in the r600 code so far, I wrote the original drm over a few days and handed it over to AMD to continue on with, as I wanted to concentrate on the kms work. Hopefully I can get some time to look at it over the next while (yeah right, new baby still not here).

James Purser: LCA 09 Conflicts

http://jamespurser.com.au/blog/LCA_09_Conflicts

Sigh looks like this LCA is going to be just like the last one I went to, full of scheduling conflicts :)

On the first day of Miniconfs we have the Business Stream, a MythTV stream and a DB stream.

On the second day of Miniconfs we have the second day of the DB stream, the Sys Admin stream, Multimedia and Virtualisation.

That's not even counting the main conference itself which has things like PHP Architecture, Scalability, and Security, Using Asterisk for Fun and Profit and Introduction to Django all in the same session times!

Sigh.

Erik de Castro Lopo: Hackfest in the House that Hack Bought.

http://www.mega-nerd.com/erikd/Blog/NewHouse/hackfest_1.html

Just before Newtonmas (also known as xmas to some) I had a small hackfest in the new house that my wife and I are calling "The House that Hack Bought". We had horms, AfC, Scott, raster, kfish, pmiller and myself hacking and chatting from about 10am.

There were 5 of us in the living room:


hackfest living room

while kfish and pmiller hacked in the sun room:


hackfest sun room

and Scott even managed to get a bit of hardware hacking done in the kitchen:


hackfest sun room

It was a great day. Thanks to all who participated.

Dave Airlie: Kernel modesetting pull request sent

http://airlied.livejournal.com/64271.html

So I sent a drm pull request that includes the kernel modesetting core + intel i915 driver supporting it.

This is a major milestone for a project I started working on in a previous job, and I barely remember burning through the initial code for the initial prototype in a week of little sleep.

To enable the code you need to set the CONFIG_DRM_I915_KMS, this isn't enabled by default, as we don't have a userspace that supports it available yet for general consumption. If you enable kms now, you will more than likely get a broken X for your trouble as the kernel drivers aren't compatible with having userspace drivers trample the hardware.

So where is ATI at?

although we are shipping radeon code in F10, the code is based on the TTM memory manager, which isn't really in an upstreamable
state in its current form. Hopefully a newer TTM codebase might become available that can be used upstream. If that doesn't happen, we might rearchitect the core memory manager code of the radeon system now that we have the API mostly proven. So I'm not sure when we will upstream it, it all depends on how much time I can work on it.

Baby status: due today, no sign yet, will severely impact amount of time I spend on this stuff :)

Mark Greenaway: Sharpening knives

http://certifiedwaif.livejournal.com/335946.html

Having used Paige's nice sharp Global knife, I knew going back to my not so sharp knife was going to be unbearable. I always want to be able to get the best out of what I have.

I've got a Japanese cook's knife, and a French style paring knife. You might ask why I chose such an odd combination. Of course, there's a simple explanation - I had no idea what I was doing when I bought those, I just wanted something better than what I was using.
My Mum bought me a diamond steel last year for Christmas, which I've been using to sharpen and hone both my knives. Anyone who knows anything about knives is by now recoiling in horror, because they'll know that Japanese and French knives are quite different, and you shouldn't be using French sharpening technique on a Japanese knife. French knives have much thicker blades, and are usually sharpened on an angle of 20 to 30 degrees. A stone is best, but a few quick swipes with a diamond steel will keep your French knife in good condition for months at a time until it needs sharpening on a stone or machine again.
Japanese knives, with their much thinner blades, need to be sharpened differently - the industrial diamond on a diamond steel is too coarse. They're meant to be sharpened so that the edge has an angle of 10 to 15 degrees. Everything I've read, and been told by people in knife shops, says that you should use a stone. I resisted buying a stone for a long long time, because I'm a miser and hate spending money when I think I've got something that should already do the job. My brother, who's been sharpening his knives on a stone for a long time, also told me that the technique is difficult to learn.
After I gave up on the steel and bought yet another tool for sharpening, I'd have to say the result was worth it, and the while I certainly haven't mastered the technique, it's not that hard to get started. There's a pretty good explanation here that I was able to follow without too much trouble.
You might wonder why the French and Japanese knives are so different. French cuisine is very different from Japanese, with the former having emphasis on complicated technique, while the latter seems to emphasise careful preparation and presentation of ingredients, often raw e.g. sushi. So one possible explanation is that the Japanese knives are designed for the more precise and intricate cutting required by that cuisine, while the French just want to cleave through the vegetables so they can get on with making the demi-glace.

Disclaimer: I am not a chef. I haven't mastered any cuisine. This is pure speculation. Get off my lawn.

Mark Greenaway: Guitars cost too much AND Chords

http://certifiedwaif.livejournal.com/335851.html

I went to Allans Music today hoping to get a cheap jazz guitar, or at least a cheaper jazz guitar. No such luck, even though some of the guitars were substantially reduced, they were still way out of my price range. Guitars are getting really expensive, although good guitars always have been. I think unless I'm willing to put down some serious cash, I'm going to be rocking the Strat for a few years yet. One of these days, I might just throw caution and good financial sense to the wind and buy the instrument I really want.
While I couldn't afford a new guitar on a student budget, I could afford to get a book. After having a look around, I found a nice book called the Chord Factory, from Berklee Press. Guitar players in jazz groups spend most of their time accompanying soloists, and the chords can get pretty advanced. Most of the chord books I've seen give you page after page of chord forms in every possible key, and then the implication is that you should memorise them, or maybe look them up as needed. I've never found this approach very useful - I'd much prefer to understand how the chords are built and how I can build voicings to suit my needs in a particular musical situation. I'd also really like to know how these chords are meant to be used. The closest I'd ever seen to what I was looking for was Chord Chemistry by Ted Greene, but that wasn't quite what I wanted either.
I worked out how to build voicings for major and minor chords with root notes on any string, got most of the way with dominant, minor and major seventh chords, and have no idea what to do with ninths and further extensions. I don't know how to voice those chords on guitar either, and didn't have much idea how to started. As the name suggests, the Chord Factory book is all about learning approaches to building chord voicings, rather than learning a couple of chord voicings by rote and hoping they're always going to be enough, no matter what your sadistic band leader puts on your music stand and expects you to play.
Just as important is that the book also begins to explain how to use these chords in a progression, which I've never been able to get any understanding of before. Finally ...

Mark Greenaway

http://certifiedwaif.livejournal.com/335612.html

One of my house mates got a Global cook's knife yesterday. She wasn't used to such high quality (read: sharp) knives, and cut herself in the first couple of minutes. We've all done that - it's a rite of passage. She was nice enough to let me try it, and it's ridiculously good. Of course, now I want one.
Musically, I've been a little uninspired since the Science Revue finished up. I think I'm finally coming out of that, and feeling like playing again. What I'm finding fun at the moment is listening to sax players, and trying to play very simple sax pieces. I read a quote from Richie Blackmore that said in part "The average sax player is much better than the average guitar player". Having played with a few sax players now, I can believe it. But what's more interesting than whether sax players are better or not is that sax players tend to have a different approach than guitar players, and trying to imitate that is helping me break out of my rut. In particular, sax players don't tend to play notes that fall easily under the fingers of a guitar player, so you end up sounding a little different just because of that.
I'd really like to find someone to play with, so maybe I should make that a priority.

Erik de Castro Lopo: learnHaskell :: Problem -> IO Solution

http://www.mega-nerd.com/erikd/Blog/CodeHacking/Haskell/learning_haskell.html

Over the last week or so I've been learning Haskell. Unlike a previous attempt to learn Erlang I think this one will actually end up bearing fruit. The main thing that slowed down my attempt to learning Erlang was that I didn't have a task to apply it to that exploited the strengths of the language.

For Haskell I have a task that is ideally suited to the language and plays to its strengths; writing a parser for an Javascript-like language. Just like when I learned Ocaml I am jumping in at the deep end with a difficult problem and learning the language on the way (ie as a side-effect of tackling the task itself).

Normally my tool of choice for this task would be Ocaml and I did in fact start out writing a parser in Ocaml using the Menhir parser generator. Menhir creates a parser from an LR(1) grammar specification where the LR(1) means that the grammar is left recursive and must need no more than one token look-ahead to resolve ambiguities. Over two days of intense hacking I made quite a lot of progress on the grammar and then hit a wall; numerous rather incomprehensible shift/reduce and reduce/reduce warnings plus a part of the grammar (raw XML embedded directly into the source code) which was not context free and for which I could not see any possible way of parsing with only one token look-ahead.

Since I already knew Ocaml, I looked around at some of the other parser generators for Ocaml like Aurochs and PCL. Aurochs uses Parsing Expression Grammar (or Packrat parsing) and seemed interesting, but was rejected because it seemed to gave very little control over the Abstract Syntax Tree it generated. PCL on the other hand was a monadic parser combinator library which is basically a port of Haskell's Parsec library to Ocaml. The main problem I saw with PCL was that it used Monads and lazy evaluation, neither of which are very common in standard Ocaml code. PCL was also rather new and I wasn't sure if it was stable and mature enough for quite an advanced parsing task.

Of course I had been hearing good things about Haskell's Parsec library for a couple of years and decided that this was a good time to give it a try. The interesting thing about Parsec is that it uses lazy evaluation to provide what is effectively infinite token look-ahead. Obviously, a Parsec grammar should be written so that it only uses more than one look-ahead when that is absolutely necessary.

With a bit of googling I found a bunch of examples using Parsec for simple things and that was enough code to get me started. A week later, after an IRC question answered by Don Stewart, a bit of help from Conrad Parker and a question answered on the Haskell Cafe mailing list, I am almost as far along as I got with the Ocaml version of the parser.

My impressions of Haskell and Parsec so far are as follows:

All in all, I'm really enjoying my foray into the world of Haskell.

James Purser: Sweet Potatos, Tomatos and YAJZ

http://jamespurser.com.au/blog/Sweet%20Potatos_Tomatos_and_YAJZ

I haven't blogged in a little while, so I thought I would do a quick update on the Garden.

First up we have our Cherry Tomatos which are just about ready to pick:

Seeing as Ms 3 is our resident Tomato fiend, she'll have the honour of picking the first batch.

Next we have an update on the Sweet Potato. As you can see it seems to have been a successful planting. The greenery is running riot and there are plenty of roots coming off the old sweet potato:

And finally, it wouldn't be a garden report without YAJZ (Yet Another Jumbo Zuchinni):

Simon Rumble: Lunch in Coffs

http://www.rumble.net/blog/index.cgi/travel/Lunch_in_Coffs.html

Latitude: -30.289268, Longitude: 153.122356

-30.289268, 153.122356

Geo: -30.289268,153.122356
Lunch in Coffs
We've just arrived in Coffs Harbour after an early start. We're heading up the coast to Uki for a New Year do. We being Don, Christine, Eric, Holly and I. Rachel, Mikey, Leonie, Mark, Lee and Nick are in cars behind us.

Contact me

Martin Visser: Switching to Internode

http://marty.sunriseroad.net/2008/12/28/switching-to-internode/

Well after a few month’s deliberation, I decided to switch to Internode as my ISP last Tuesday. While I wasn’t unhappy with iinet as a service provider, it really came down to a value-for-money decision. Having 4 teenagers in the house, meant that we seemed to be every month hitting 10+10GB quota I had with iinet. And while some of them could make use of the off-peak download time by scheduling downloads, it really isn’t all that convenient. And all to often it seemed that at least once a month someone would get the time wrong to start or finish downloads so we would have inadvertant creepage into the peak quota. However for the same $70 is was spending at iinet, I could get 40GB monthly quota, with no time restrictions - so hopefully there will be no more draconian filtering by yours truly to keep us under quota.

Internode (like iinet) are very Linux friendly (in that they can provide support for Linux users if required) but more importantly they both provide good unmetered repositories/mirrors of open-source software. Internode seems to have the edge though, especially now they are a Sourceforge mirror. They also have some nice unmetered media with quite a few radio streams. Another clincher for the recent decision was that Internode now provide ABC’s iView unmetered, which all made good use of on iinet. According to my kids the gaming servers are well supported and have low “ping” times, so all should be good on that front. Actually one nice thing the Internode does is publish a very clear list of IP address ranges that are unmetered. I might try to combine this info with the netflow info I have been grabbing from my router to more accurately feedback to my family on their metered/unmetered usage profiles.

We also have made use of iinet’s bundled phone PSTN and VoIP services. However this actually proves to more costly than what it should be. With iinet to get my $70 ADSL plan I needed to bundle the phone service at around $33 (though I got free VoIP access). But with Internode, I can get the $70 ADSL (with 2x quota) and I can buy my phone service from Telstra (I’ll choose the $19 budget plan), and then I can buy a $10 VoIP service which comes with $20 phone credits. All up, I expect to save maybe $20 a month and get double the data quota. Internode by all accounts have a good service reputation, so I really have no qualms in switching.

So I am still happy to recommend iinet for their level of customer service, however despite a few calls to them indicating I was about to leave, and giving them an opportunity to keep me, they really couldn’t match Internode’s pricing.

Hopefully all goes well.

Mark Greenaway: Sound proofing a rented room

http://certifiedwaif.livejournal.com/335275.html

The room I'm renting is in a house on a semi-major road. Most of the sound seems to be coming in through my window. Does anyone have any ideas? I think heavy curtains might help. The ideal solution would be double glazed windows, but as I'm a renter and don't own the property I'm limited in what I can do.
It looks like I'm about to become an expert in cheaply sound proofing a room.

James Polley: Boxing day Tweetable Tweets

http://feedproxy.google.com/~r/zhasper/~3/TFXEHcFPCvU/

Okay, so I lied. Some of these are from two days ago..

Stilgherrian
stilgherrian “Christmas ruined as Sarah Palin shoots Rudolph” http://is.gd/cYaU
Stilgherrian
stilgherrian Just discovered NewsBuiscuit! “Children ‘getting over-excited’ about going to church on Christmas morning”: http://is.gd/d6pz
Harley Dennett
harleyd I just had to explain who ABC radio host Julie McCrossin was to an ABC reporter who rang seeking gay christian sources. Yay ABC cuts.
Mike Cannon-Brookes
mcannonbrookes RT @barconati Awesome post. Dan talks about the benefits of deploying Confluence enterprise wiki at the Powerhouse Museum http://tr.im/2l9b

Mark Greenaway

http://certifiedwaif.livejournal.com/334941.html

I've been thinking about how to take my guitar playing further. This year I found that I really enjoyed playing for people, so I'll probably keep looking for opportunities to do that. I guess the short version of what I think I should do is


How I'm going to find the time is left as an exercise for the reader.

Mark Greenaway

http://certifiedwaif.livejournal.com/334816.html

My new house mates got Wii Fit for Christmas. They're jogging through a virtual landscape in our living room. So weird.

James Polley: Munging old URLs to match Wordpress’ expectations

http://feedproxy.google.com/~r/zhasper/~3/WkqoAtqxup0/

One of the downsides of having spent years messing with my old Drupal blog is that I’ve ended up with a bunch of different permalink styles: to pick three posts at random, http://zhasper.com/zhasper/harry_potter_done, http://zhasper.com/2007/09/linkbloggery, http://zhasper.com/?p=631. Fortunately, I’m only running this blog to give myself a place to vent, so I don’t care about lost traffic. If I did care, this would be a problem.

I’m using the “Platinum SEO pack” plugin, which does a good job of handling URLs that don’t quite match the same schema that Wordpress is using - for instance, if you visit http://zhasper.com/linkbloggery, it’ll figure out that you meant the second URL in the list above. Unfortunately, it’s not perfect - and my old blog had way too many variations for anything to cope with.

So, I’m going through and doing what I can to fix the low-hanging fruit. URLs in the second form, /YYYY/MM/title, already work fine. URLs in the first form need to have the /zhasper/ removed, and need all the _s turned into -s. I accomplish both of these through a bit of RewriteRule magic:

RewriteEngine On
RewriteBase /
RewriteRule zhasper/(.*) /$1 [R=301,L]
RewriteRule (.*)_(.*) $1-$2 [R=301,L]

This is quite definitely not the neatest way to achieve this. In the example above, it requires three excess round-trips between the server and the browser:

The 301 in the RewriteRule means that the server tells the client that this is a permanent redirect - the content will never be at the old address, please update your bookmarks. This doesn’t make much difference to your browser - but crawlers such as Google should use this as a signal to update their index, and send any link-love directed at the old link to the new link.

If you didn’t have the redirect at all, Google wouldn’t know that /zhasper/harry_potter_done and /2007/07/harry-potter-done were the same page - it would think that the latter was just a more-recently-seen page which mysteriously had similar content to the old page.

If you go with a temporary redirect (by just using R on its own, or by stipulating [R=302], Google won’t know to update its index: it will still come back later and check the old URL, just in case the page has moved back there.

There are definitely better ways to achieve this - suggested enhancements are welcome :)

James Polley: Google Webmaster Tools: I don’t understand them.

http://feedproxy.google.com/~r/zhasper/~3/cNTnvGB7dWI/

I’ve seen a few hits on my site to http://zhasper.com/user/, or pages underneath. This seems to be because there used to be content there, and Google’s cache hasn’t (or hadn’t at the time anyway - it seems to have mostly caught up now).

I don’t want this, so I went to the “Remove URLs” tool, under Tools in the Webmaster Console.

The page says:

Before you begin, you must make sure that Google and other search engines will not crawl the content you want to remove from our search results.

To do this, ensure that each page returns an HTTP status code of either 404 or 410, or use a robots.txt file or meta noindex tag to block crawlers from accessing your content.

Okay, so it needs to return a 404. Easy - there’s no content there anyway, it’s already returning a 404. Double-check:

zhasper@bridgitte:~$ wget http://zhasper.com/user/
--2008-12-25 17:03:31--  http://zhasper.com/user/
Resolving zhasper.com... 88.198.1.123
Connecting to zhasper.com|88.198.1.123|:80... connected.
HTTP request sent, awaiting response... 404 Not Found
2008-12-25 17:03:31 ERROR 404: Not Found.

Excellent. So, I request the whole directory to be removed from the index.

Some days later, I come back and check, and my request for removal has been denied. There’s a little question mark beside the word denied, obviously further details, so I click on it:

Your request has been denied because the webmaster of the site hasn’t applied the appropriate robots.txt file or meta tags to block us from indexing or archiving this page.

No shit - I didn’t put anything in robots.txt because it’s returning a 404, and your instructions say that’s all that’s needed.

Grrr.

I *think* that everything under /user/ has been removed (there’s certainly nothing in the index any more), it’s just /user that’s not been removed. I don’t understand this - /user gives a 404 also, and the content shown in the snippet is the old Drupal content.

(obdisc: this is a private blog, all opinions are my own and not those of my employer, who happens to be Google. There’s probably something obvious that I’m overlooking - hopefully I’ll have another blog post soon with an update on what that is)

Udpate, 5 minutes later: Duh. Read the next paragraph, idiot:

If you’re requesting removal of a full site or directory, you must use a robots.txt file to block crawlers from accessing this content.

I’m requesting removal of a full directory. So….

Conrad Parker: Tractorgen on github

http://blog.kfish.org/2008/12/tractorgen-on-github.html

Tractorgen is now on github:

REPOSITORIAL

The contents of this revision controlled document repository are a computer
source code implementation of TRACTORGEN, being a model of ASCII tractor
mechanics.

It is recommended that one study these documents closely in order to better
understand the finer details of the subject at hand. The authors firmly
believe that only through such preparation, preferably during the course of
one's daily study regimen, can a deeper appreciation of the theory be
attained.

As a side note, it has been noted by correspondents that it is possible to
derive a computer readable binary executable from these documents through
the use of sophisticated compiler technology. On the off chance that any
readers would wish to pursue this path, we include the apparent preparation
for doing so herein, as quoted:

$ automake -a
$ autoreconf

Upon completion of this procedure, which we expect should take on the
order of one to two weeks (of course the actual time depends on the
staffing resources of your local computer centre), a new document shall
be generated _as though from nought!_ [emphasis added]. The name of
this document is expected to be "configure", and it may itself be
executed thus:

$ ./configure

We recommend scheduling a vacation!

Upon your return, type "make", then "make install", and prepare your
experimental apparati forthwith:

$ tractorgen

Generates ASCII tractors.

Commit messages

One must eschew the typically terse and perfunctory style of commit messages that are common in software projects, and ensure that the purpose, significance, and experimental procedure for each incremental change are appropriately recorded.

Obviously, commit messages are a good place to store source code for important tools: 9112c05.

         r-------
        _|
       / |_______\_    \\
      |          |o|----\\
      |_____________\_--_\\
     (O)_O_O_O_O_O_(O)    \\

Michael Fox: Just about Christmas and nearly the conclusion to another year.

http://blog.heimic.net/2008/12/24/just-about-christmas-and-nearly-the-conclusion-to-another-year/

Well it is nearly Christmas, so I thought it would be a good time to make a quick post. Wish everyone a Merry Christmas and a Happy New Year.

Only days away from the conclusion of another year, I can’t believe it. I bet I end up saying something similar this time next year. I am sure everyone will agree the year just goes on by so quickly without much thought of what we had hoped to achieve in the period.

I hadn’t announced it here yet, but now is a good as time as any. For those who don’t know already, my wife and I are having our first child. The baby is due on 5th May at this stage, which is a day shared with another family member who has a birthday on this same day. Soon see if things happen on that day or not.

Have a Merry Christmas.

Conrad Parker: Release: HOgg 0.4.1

http://blog.kfish.org/2008/12/release-hogg-041.html

A new release of HOgg, on Hackage:

This contains updates to work with Hackage, the Haskell source package system; and also a new hogg man subcommand to generate man pages for subcommands.

Updated for Hackage

Hackage is Haskell's source packaging system. It makes it very easy to keep up to date with bleeding-edge releases.

You'll need the cabal command. This is already in Gentoo (emerge cabal) and Arch Linux (pacman -S cabal-install). If you're on a system where cabal is not already packaged, you'll first need to install GHC (eg. apt-get install ghc6 on Ubuntu 8.10 or Debian Lenny systems), then:

$ wget http://hackage.haskell.org/packages/archive/cabal-install/0.6.0/cabal-install-0.6.0.tar.gz
$ tar zxf cabal-install-0.6.0.tar.gz
$ cd cabal-install-0.6.0
$ chmod +x bootstrap.sh
$ ./bootstrap.sh

This will download and build the packages required to set up cabal. From there, a new Haskell package like hogg can be installed by simply doing:

$ cabal update
$ cabal install hogg

This will build and install hogg into $HOME/.cabal/bin (which of course you should add to your $PATH if you actually want to use anything you install via cabal :-)

man page output of self-documentation

hogg already generated its own help text, with runtime checking of example syntax. This release adds a hogg man subcommand which generates the same help text in Unix man page format:

$ hogg man man

.TH HOGG 1 "December 2008" "hogg" "Annodex"
.SH SYNOPSIS

.B hogg
.RI man
[
.I OPTIONS
]


.SH DESCRIPTION
Generate Unix man page for a specific subcommand (eg. "hogg man chop")

.SH OPTIONS
  -h, -?  --help     Display this help and exit
  -V      --version  Output version information and exit

.SH EXAMPLES
.PP
Generate a man page for the "hogg chop" subcommand:
.PP
.RS
\f(CWhogg man chop\fP
.RE
.SH AUTHORS

hogg was written by Conrad Parker

This manual page was autogenerated by
.B hogg man man.

Please report bugs to <ogg-dev@xiph.org>

James Purser: More Gems

http://jamespurser.com.au/blog/More_Gems

Having three kids, you are always going to hear some wierd and wonderful things and these past seven days have not been any different.

Yesterday I was having a "discussion" with mr 10 about his behaviour and the subject of presents at christmas time came up. He was confident that he would be recieving presents, no matter what his behaviour, when his sister miss 5 decided to pipe in with "You should listen to daddy, he went to school with Santa!".

This however was not the funniest thing we heard from our flock of kinder. A few days ago, we were leaving Wollongong Hospital after visiting Karins dad (who had a stroke last monday, while he's been laid low, it's not as bad as it could have been), and we got stuck at the lights. Karin rocked the car back and forth on the plate in an effort to hurry up the lights. Miss 3 got very cranky when we didn't immediately start driving off and said so "What are we waiting for, a stop go party? Get moving!"

Got to love kids :)

James Polley: Story of the day: The voices in your head are real.

http://feedproxy.google.com/~r/zhasper/~3/b_HY1WhKDU8/

From the normally staid ABC news website comes this gem:

Paranoia is much more common in modern society than previously thought, says a British doctor, who warns it could lead to major problems in society.

Oh noes! Rampant paranoia! Is this what’s been making me think crazy thoughts lately? Our society is in danger! Quick people: we must be vigilant! Examine your own thoughts for any hint of paranoia, NOW!

Dr Daniel Freeman from the psychiatry institute of King’s College London says almost a quarter of the population experience regular paranoid thoughts,

One in four? Then it’s almost certain that I’m paranoid. Woe is me! Whatever could be causing this epidemic of paranoia?

driven by an avalanche of sensational stories in the media.

Oh. Right. Good to see that you’re helping there, doc!

Dave Airlie: r500/600 tv-out merged but needs enabling

http://airlied.livejournal.com/64021.html

So we merged r500/r600 via atombios TV-out support, but we haven't enabled it by default.

You need to add

Option "ATOMTvOut" "true" to xorg.conf to enable it.

We'll hopefully get to fix up some of the remaining corner cases and issues or enable it at
least on a card by card basis.

Pia Waugh: Moving

http://pipka.org/blog/2008/12/23/moving/

We are moving at the moment. More details on this soon, but if you are trying to get in contact with either of us, please give us aweek or two to get back to you :) Otherwise call/sms us if it is urgent.

Moving to the country, gonna eat a lot of peaches.

Jeremy Visser: Takeaway lights script

http://jeremy.visser.name/2008/12/23/takeaway-lights-script/

I just stumbled across a simple yet fun script I wrote over a year ago to animate your keyboard LEDs:

#!/bin/sh

LED="setleds -L"
SLEEP="sleep 0.2s"

$LED -num -caps -scroll

if [ "$1" = "-c" ] ; then
	exit 0
fi

while [ 1 ] ; do
	$LED +num
	$SLEEP
	$LED +caps
	$SLEEP
	$LED +scroll
	$SLEEP
	$LED -num
	$SLEEP
	$LED -caps
	$SLEEP
	$LED -scroll
	$SLEEP
done

It will simply pulsate the keyboard LEDs from left to right. Note that this script only works while logged into a tty — it does not work under X11.

Ian Wienand: Streaming various radio streams to FStream on the iPhone

http://www.technovelty.org/toys/iphone-streaming.html

FStream is a really neat streaming radio program for the iPhone. Although it supports various WMA streams, I found that it did not successfully work with some of the Australian ABC WMA streaming radio services.

The most reliable method seems to simply use a low-bandwidth MP3 stream over HTTP (24 kbps sounds fine and works great even over Edge). I could find a number of other blogs, etc. with static methods for streaming, but nothing that reliably did on-the-fly conversion of an incoming stream.

My solution is simple Python HTTP server I'm calling stream2mp3. It uses mplayer, lame and a few pipes to take the incoming stream (which is pretty much anything mplayer can handle, which is pretty much anything unencrypted) and spit it out as a low-bandwidth MP3 stream over HTTP.

It seems to reliably handle dropped and closed connections, and clean-up after itself. I'd certainly be interested in any bug fixes or suggestions. I guess the major disadvantages is you need a dedicated server (get yourself a linode!), it only handles one connection at a time, and if you want multiple stations I guess you run multiple instances on different ports.

With this, you can be sitting in traffic on the 101 heading to San Francisco and, with some local radio, it's just like you're sitting in traffic on the M2 in Sydney! Here's a screenshot:

~/bin$ python stream2mp3.py
Creating WAV fifo /tmp/incoming.wav
Creating MP3 fifo /tmp/output.mp3
Serving <mms://media3.abc.net.au/702Sydney> on port XXXX
mplayer running as 8524
lame running as 8525
mobile-XXX-XXX-130-107.mycingular.net - - [23/Dec/2008 18:59:22] "GET / HTTP/1.1" 200 -
[radio plays until I stop it...]
connection lost
cleanup complete, ready

James Polley: ASA censorship update: Screengrabs!

http://feedproxy.google.com/~r/zhasper/~3/s2XUJe4gJZ0/

Re censorship of flight details: Tim Bennet at Electron Soup was faster than me and got screengrabs before the details were censored. Go satisfy your curiousity at his blog.

Mark Greenaway

http://certifiedwaif.livejournal.com/334358.html

I've moved share house again - this time from Stanmore to Haberfield. It was sad in a way - I've lived in or near Newtown for five years now.
The move was a marathon effort. My parents are getting older, so rather than try to get my family to help me move, I hired Two Men and Truck. They delivered boxes to me on Thursday, for a move on Sunday morning. I've moved house so many times before that I know that there's no such thing as overpreparation, so with help from friends, particularly Dee and Jack, I tried to pack my entire life into boxes as much as possible before the movers arrived. While I'm glad the process was spread over several days, it was physically tiring and I'm quite drained.
Because I put so much effort and thought into preparing for the move, the actual moving day went off without a hitch. As [info]thaytan said, professional removalists work fast. The entire contents of my room and study area were packed in under half an hour, and the whole move was completed in two. We drove to Haberfield, they unloaded everything and off they went. Jack and I went back for fragile things like computers, guitars and tube amps later in the day.
The new house is, um, interesting. It's big, and has lots of potential, but also a few quirks. Some highlights - dining room, dishwasher, enormous garden, large rooms. Some parts of the house need some love. I also don't know yet if I'm going to be here very long, because the lease is up in February, and people in the house haven't quite decided what they want to do. But for the time being at least, things are good.

James Purser: LCA 2009 - Are You Going?

http://jamespurser.com.au/blog/LCA_2009_-_Are_You_Going

Hey guess what, in less than a month one of the best tech conferences in the world is going to be happening in Hobart, are you going to be there? I know I am.

I've been to LCA once before and I have to say it was pretty damn impressive. The gathering of minds and the opportunity to pick the brains of some of the brightest people in our community is almost priceless. Combine that with the fact that it's going to be in the only State I haven't actually been to/lived in, and I couldn't resist.

Michael Fox: Ubuntu annoyances

http://blog.heimic.net/2008/12/22/ubuntu-annoyances/

Downloaded the Ubuntu 8.10 AMD64 alternate image. Proceeded to install. Setup LVM etc, then install continues. It then stops and prompts you to insert another disc. It would appear it wants the Ubuntu 8.10 AMD64 desktop disc. Lucky I have a copy, it then proceeds to not accept it, yet the disc id matches exactly that it is asking for.

Grrr..

Andrew Cowie: Positive Y

http://research.operationaldynamics.com/blogs/andrew/software/java-gnome/cairo-arcs.html

The excellent Cairo graphics library has a simple function to draw arcs; in C it’s cairo_arc(); from java-gnome it’s Context’s arc() method, etc.

Quite unsurprisingly they define increasing angles as going from the positive x axis on toward the positive y axis. Nothing unusual about that. The only thing that was surprising is that they even mention this in their documentation.

I should know better.

What I totally missed was the implication of this. I didn’t quite clue in that the positive y direction in screen positioning and page drawing is down, and so increasing angles go clockwise. Using cr.arc() to go from 0 to say π/3 radians does not give a rise of 60° like I expected; it gives this:

cairo arc positive

Whoa. This is not the counter-clockwise increasing θ like we’re all used to seeing in normal Cartesian or Polar co-ordinates. But it is indeed increasing toward the positive y axis. Oops. Oh well :)

So I made this illustration and added it to the documentation for Context’s arc() method. Really it’s mostly about pointing out which direction positive y is, but when I’ve learned something like this the hard way, I do my best to try and incorporate that knowledge into our public API. With any luck others can be spared my folly.

Drawn with Cairo, of course!

AfC

Update: Some people have pointed out that you can use a transformation matrix, and if you happen to (say) mirror across the horizontal axis then the clockwise notion would no longer apply. Fair enough; but if you have forgotten that +y starts out going down, then you’re not going to think to do such a flip in the first place.

Andrew Cowie: You never know

http://research.operationaldynamics.com/blogs/andrew/travel/germany/rhone-beaune.html

I was pleased to find a decent l’Entrecôte restaurant in east Berlin around the corner from where I was staying.

I ordered what looked like it might be a promising little Côte de Rhône. Somewhat to my chagrin, a bottle of Côte de Beaune showed up instead. Which turned out to be delightful.

Hautes-Côtes De Beaune 2005
“Clos De La Perrière”
Domaine Parigot Père et Fils
Meloisey

Which just goes to show that what you ask for has little to do with what’s actually going to work with the meal you’re having.

AfC

Jeff Waugh: More mainstream media love for OpenAustralia

http://bethesignal.org/blog/2008/12/20/more-mainstream-media-love-for-openaustralia/

Totally awesome to see Matthew Moore covering OpenAustralia’s efforts to bring the register of members’ interests to the web:

Given the fortunes spent in the nation’s Parliament, and Kevin Rudd’s professed desired for more transparency in government, it seems absurd that volunteers are left to do the job any self-respecting parliament would have done long ago.

via Interests of MPs to go online - it’s about time.

Simon Rumble: If programming languages were religions

http://www.rumble.net/blog/index.cgi/geek/Languages_as_religion.html


Perl is indeed like slitting the throat of a live chicken and smearing its blood and entrails on an effigy of your enemy.

If programming languages were religions... thanks to Raz

Contact me

James Polley: Crikey! I got a half-mention!

http://feedproxy.google.com/~r/zhasper/~3/2osnttsNNvg/

Stilgherrian alerted me to the fact that I got a mention on Crikey today - or at least, yesterday’s post about ASA’s censorship of flight records did.

I’m flattered, but also slightly pissed. If you clicked on that link, you’d have been asked to provide your credentials as a paid-up member of Crikey - or at least, to take a 21-day free trial. I had to do the latter, in order to read what had been said. Hopefully if I’m ever mentioned again on Crikey it’ll be within the next few weeks - because after that my free trial will have expired, and I’d hate to have to pay for a membership just to see how I was being quoted. There’s plenty of good reasons to pay for a membership, and I’ve been toying with the idea for a while - but that’s not the reason I’d prefer to be my primary reason.

So yes, I signed up for the trial and got to read the article. There’s a nice link back to my blog - except with a missing “http://”, so the link directs readers to http://www.crikey.com.au/Politics/zhasper.com/2008/12/censorship-of-flight-details/ and not to my blog. So, of course, I got… well, actually, I got 27 people hitting that page directly, no doubt through manually fixing the URL.

Actually, I should say that I got two half-mentions. I also had 61 visits from http://civilair.asn.au/. Ben Sandilands, the journalist wrote the Crikey piece, seems to be active there as well (at least: I found a story from him just by skimming the front page) - I’m guessing the two are related. As with Crikey, I can’t see the content on this site without registering. Unlike Crikey, it’s not possible to register here - so I’m still in the dark about where the traffic came from.

So, overall, a good day for blogging. Apparently I’m not the only person interested in why ASA censored flight details - I just wish I could see what the other interested people are saying.

 — 

Unrelatedly, I caved and ordered x-plane tonight. If I had a car, I’d be at the airport on one of the mounds right now, having spent the last half-hour watching the last few planes scurrying to get off the ground before curfew kicks in. I seem to be back in *that* phase.

Michael Fox: Lots of screen resolution = sweet

http://blog.heimic.net/2008/12/19/lots-of-screen-resolution-sweet/

Just purchased a Benq E2200HD LCD monitor. It’s a 21.6″ widescreen with 1920 x 1080 resolution. Has d-sub, DVI and HDMI 1.3 inputs.

All I can say is that running at native resolution is unreal. It’s like literally having dual monitors, as the screen resolution is so high.

Will have to hook up the work laptop to it when I am working remote, as it will make life so much easier. Very impressed.

All I need now is for the onboard ATI 3200HD video card to be much more widely supported on Ubuntu/Linux. In the meantime 2D use works well enough so I think a Ubuntu 8.10 desktop install will be in order, as I think a Ubuntu/Linux system would be good on this system. Will then run VMware Workstation for any Windows XP Pro guests I need to use.

Monitor was a good price too, they retail for about $239 - $249 which is a good buy, considering a few years ago my first 17″ analog LCD monitor was $705 or so (which is still going).

Sonia Hamilton: udev, HAL, DBUS

http://soniahamilton.wordpress.com/2008/12/19/udev-hal-dbus/


A good post from Glen Turner on SLUG about udev, HAL, DBUS (in the context of GSM modems):

 - you insert the device
 - UDEV tells HAL that it has been inserted
 - HAL looks up a XML-based "information" file. These are where the
   rubber hits the road.  The system files are in
     /usr/share/hal/fdi/
   and any files you may write go into
     /etc/hal/fdi/
 - HAL determines from the USB vendor/model codes it was handed
   that you've got a GSM modem. The policy files contain related
   details like which USB Serial port to use for PPP, what dialing
   algorithm to use, etc.
 - HAL pumps these details to NetworkManager, probably via DBUS
 - NetworkManager daemon chats with the NetworkManager applet to
   grab other data, such as PIN numbers
 - NetworkManager kicks off PPP using the combined information
   from HAL and the NM applet.
      

Mark Greenaway: Moving

http://certifiedwaif.livejournal.com/334203.html

Every other time I've moved, my parents and brother have helped me, and I've completed the entire move in one day. This basically killed us, especially my mother, and made the moving experience much more stressful. This time, I'm hiring removalists and packing well in advance. We're moving on Sunday, but because I know packing always takes longer than I think, I started yesterday, with help