Archive for the ‘Development’ Category

Ugly Code And Why It’s Good

Tuesday, February 17th, 2009

While helping a colleague with a defect regarding things that should not happen but were and caused the whole tower of sticks to come tumbling down, I noticed a block of code that follows more or less the gist of the pseudo-sample below:

if(lots of conditions)
{
    doSomeStringCopies();
    if(a certain condition)
        doSomething();
        doSomethingElse();
    doFinalStringCopies();
}

Bear in mind that the consistency of indentation of the actual code was nowhere as nice as above.

Notice the problem? doSomethingElse() will be called irrespective of the secondary condition, resulting in bad things happening because a certain field does not contain a valid value for the doing of something else, but is entirely valid in terms of the business rule.

This is why you always surround your compound code structures with braces: because you never know when someone’s going to slide a “fix” into your code and neglects to add the braces. Several people (who have obviously never been burnt by this problem, and if they have, they should have their keyboard license removed from them) might think that bracing a compound structure which contains only one statement makes the code look uglier or more unreadable, but it definitely makes it a lot more maintainable.

(As an aside, I have a feeling that this is one of my more poorly written entries. Shame on me, I know.)

MegaTrader I: The Premise

Monday, January 12th, 2009

A few months ago, I started working on a J2ME game called MegaTrader, which eventually fell by the wayside as I finished up on my honours work and settled into my new work. Lately, though, I’ve been spending some time again drafting ideas and notes on the game; notes I thought I’d write up here for the sake of commentary and the sake of getting it down in written form.

(more…)

HP-UX, shared memory, and you

Monday, December 1st, 2008

My current project at work involves doing some investigation into creating a daemon to allocate memory to processes using a pool of shared memory (SHM).

The reason for this is that the implementation of the C runtime (CRT) library’s memory management routines on HP-UX does not shrink the heap of a process. This effectively means that if you were to allocate a 512MB block of memory and then release that memory again, the operating system would still report your process as using 512MB of memory. Because of this, long-lived processes (such as services) that may use large amounts of memory to do processing at some point eventually dominate the memory usage of the system, even though they are actually using only a small part of this expanded heap on average. More specifically, the OS is basically reporting that there are 20 instances of a single service each using 1GB of RAM! Shared memory, on the other hand, obviously uses memory on the system, but since SHM isn’t tied to any specific process, it won’t cause the participating processes to display a huge amount of memory usage.

The other alternative is of course to change the way the service does processing, but this involves code changes in both the front and back-end parts of the software, so a shared memory allocator would be the path of least resistance in this case.

“But wait!”, you say, “Wouldn’t that involve changing the back-end code to make use of the new allocator anyway?” The answer to this is that, yes, it could, but there’s an easier option. The dynamic loader on UNIX uses a neat little environment variable called LD_PRELOAD which causes the shared libraries specified in it to be loaded before any other shared libraries. This allows you to easily override the CRT’s memory management routines, since yours get loaded first. This means that the amount of code that needs to be changed go from every memory allocation call to, effectively, none at all.

So we can have the manager allocate a big block of shared memory, and have the services communicate their requests for memory to the manager using UNIX domain sockets. The manager then attempts to service the request by reserving a block of shared memory for that process and passing the address back to the requesting process. The service can then map the shared memory segment into it’s own address space, use the memory for whatever it needs it for, and then tells the manager to release the memory again. Easy off bang!

Not quite, though.

HP-UX has support for both 32-bit and 64-bit operation. In 32-bit mode, the maximum size of a shared memory segment is 1GB, while in 64-bit mode, a shared memory segment may be up to 4TB in size. The systems we’re working on run a 64-bit kernel, so the maximum size of a segment isn’t the problem. The problem is that the processes themselves are 32-bit executables, and to understand why, I’ll need to talk about how HP-UX defines the memory space for a 32-bit executable.

32-bit mode implies a maximum addressable range of 232 bits, or 4GB of memory. In HP-UX, this 4GB virtual address space is divided into four quadrants of 1GB each. The first two quadrants are used for the process’ text and data segments. The third and fourth quadrants are used as a global shared memory space, with the final 250MB of the fourth quadrant being reserved for system I/O (my guess is that this is used for buffers when doing I/O operations). The global adjective means that any shared memory in the system will be (potentially) visible in any other process. Since shared memory does utilise access control when a process requests to map a segment into its address space, there aren’t any security concerns regarding that, though. What this does mean, though, is that the total amount of shared memory available in 32-bit processes is limited to 1.75GB. And by “32-bit processes” I mean all 32-bit processes currently running in the system.

Luckily, HP-UX has a feature known as memory windows. To use memory windows, the process to be executed is run using a wrapper called setmemwindow, which will execute the given command in a given memory window. The effect of this is that instead of the process having the normal 1GB global Quadrant 3, it receives a separate 1GB Quadrant 3 which is then shared by all processes belonging to the same memory window.

The idea I had is to use this feature by partitioning the services that require the shared memory pool into groups, and having them and their respective shared memory manager all belong to the same memory window. This frees up the global Q3 for other processes running on the system that might also use SHM, and allows multiple shared memory managers to execute in parallel with their own set of managed services.

The current status of my investigation, barring finding out about the above technical details, is that I’ve completed a basic manager process capable of reserving and releasing blocks of the shared memory segment to requesting processes, as well as a small test program that communicates requests to the manager. The next step is to write two programs that will perform random memory allocations, one using the SHM manager and another using the standard CRT, to get an idea of what the performance impact of the additional management layer will be.

Hopefully someone will find this useful, since I had to do quite a bit of Google-trawling to find out about all of this. If anyone wants a few of the references I used, feel free to leave a comment, and I’ll see if I can set you up.

Megatrader

Thursday, October 16th, 2008
Megatrader Main Menu

Megatrader Main Menu

For the past week, when I haven’t been working, I’ve been spending a good deal of my free time developing a J2ME mobile game. The basic premise is Dope Wars in space, albeit with less drugs and more futuristic trade goods. The inset image is the main menu screen running in the WTK emulator. Right now, I’m more or less at the point where I can actually start on getting the game up and running, having spent the time thus far on getting all the support functionality down (such as drawing text using my custom fonts and being able to easily support different resolutions, since I’ll be targeting at least QVGA and QCIF+ displays).

Initially, the game will be fairly simple, featuring only simple trading: buy at planet A, travel to planet B and sell, rinse and repeat until the time limit is hit, with random price fluctuations as per the drug busts in Dope Wars. In the future, there are a couple of distinguishing features I want to add to the game, such as competing against computer-controlled traders and being able to buy different ships which affect their cargo space and travel speed, amongst other things.

(more…)

Acceptance Testing With Selenium I

Monday, October 13th, 2008

The freelance work I’m currently doing called for some testing after I significantly changed the underlying framework’s internals. Considering I’d been spoilt with the idea of automating any and all testing when I was going through my Ruby on Rails phase, I started looking around for something similar in the PHP camp. The most important thing I had to keep in mind was that it needed to be something that was JavaScript aware, since the website utilises a lot of JavaScript fanciness.

Enter Selenium. More specifically, the combination of Selenium Remote Control (RC) and PHPUnit.

Selenium RC is a Java server application which launches instances of the browser(s) you specify, and then puts them through the paces of the tests that you define using plain old PHP and PHPUnit, checking the assertions you define. In other words, you get the effect of a real user using a real browser, without having to do all the grunt work yourself. Win-win.

The current version of Selenium RC (henceforth referred to as SRC) I’m using (version 0.9.2) works like a charm, but requires a small tweak to work with Firefox 3. When SRC instantiates a new instance of Firefox, it creates a temporary profile and installs a Selenium extension into the profile. This extension’s maximum Firefox version is still set to the Firefox 2 versions, so it will silently fail under Firefox 3, leaving you to gnash your teeth in frustration while you sift through Google to find out why the damn thing isn’t working.

Fortunately, the fix is simple. It involves unpacking the selenium-server.jar file, and changing the install.rdf located under the customProfileDirCUSTFF directory, so that the maxVersion element contains the value 3.0.* to work with Firefox 3.0.

From there on, you can either pack everything up again into a new JAR (which I didn’t bother with), or simply run the server in its unpacked form.

Next time, I’ll dish up a small sample of how to actually go about doing that funky thing we call testing with Selenium RC and PHPUnit.