Archive

Archive for October, 2010

Installing Linux

October 31, 2010 Leave a comment

I still have a hazy recollection of my very first experience installing Linux.

My brother and I had read about Linux on some bulletin board (or maybe it was a library book, not sure), and we bought slackware 3.x CDs from some online retailer. Remember the days when you had to buy CDs because downloading 700 MB was completely and totally impossible over a 9600 baud modem? Man, those were the good old days.

We waited and waited for those CDs to come in the mail, and it took *forever*. Well, it felt like forever to me and my brother, but maybe it was a week or so.

We ripped open the packaging, threw the CD into the drive, and booted into the (curses-based) text installer. A few steps later, it asked us which drive partition to install Linux into. Partition? What’s that, some kind of privacy screen? Being the clueless noobs that we were, we told slackware to blow away the existing partitions and create new ones. Little did we know we had just tossed all our schoolwork, and 8 months of work on a 3D game engine we thought would make us rich and famous.

The next few hours were pretty stressful, as we ran all over the house looking for anything we might have backed up to a 3.5″ floppy, then we searched all the 5″ floppies. No dice, all our code was gone.

On the bright side, I stopped spending all my free time on Pascal and 3D models and started focusing more on my homework. Also, we both got completely and totally hooked on Linux. Something about the whole experience either scared us into learning more, or intrigued us – we spent the next several years fiddling with every *nix distro we could get our hands on. I’ve installed (in no particular order) Slackware, Debian, Knoppix, Gentoo, FreeBSD, OpenBSD, NetBSD, Ubuntu, MeeGo, Fedora, RedHat, CentOS, OpenSUSE, SLES, and probably some I’ve forgotten.

Along the way, I’ve picked up some useful skills that I turned into a career which I owe largely to the open nature of Linux. But that’s a story for another day.

Fast forward a bit to 2010. I recently made the switch back to Linux from Windows… on my work laptop.

I’ve been using Linux fairly consistently for about 15 years, but a lot of that time it’s been on desktops and/or servers. I’ve tried all kinds of Linux distros on laptops, but nothing ever seemed to work right. The video card didn’t work, or the wireless driver crashed, whatever. And even assuming the drivers were fine and everything worked on boot, let’s face it – there’s a lot of reasons Linux is in the minority of desktop OSes.

But I digress. I installed Ubuntu 10.10 (aka Maverick Meerkat) on a thinkpad, and I was pleasantly surprised. The installer was nice looking, easy to navigate. The partitioning wizard automatically resized my Windows partition so I can dual-boot if I ever need to. Installing the graphics card driver was painless, the sound card works out of the box, and I was pretty much blown away by how accessible Linux is on 10.10.

I guess the proper way to summarize it is Ubuntu makes Linux painless / easy. Or at least, nearly painless. Evolution/exchange support is still buggy as all get out, plugging into my docking station doesn’t change my monitors, and suspend/resume/hibernate always crashes… but all things told, Linux ala Ubuntu has come a long long way.

By way of reference, I’ve had to install Fedora, CentOS, and OpenSUSE recently and not much has changed in 10 years. The desktop is still ugly and inaccessible, the package managers rely on mirrors which are broken more often than not – and OpenSUSE refused to recognize my existing partitions, I had to boot a Ubuntu LiveCD to delete them so OpenSUSE would install.

Also as an interesting data point, I found a Ubuntu 6.06 LiveCD lying around and booted it up for old times sake. Wow, I forgot how terrible Linux was as a Desktop OS back in the day. I’ve always been a Linux junkie and I LOOOOOOVE the command line… but I am very glad to see the progress of Ubuntu and I have high hopes for Unity on the desktop.

So that’s all really, just a rambling long story about my experiences installing Linux. I spend most of my time fiddling around in the kernel, but it’s amazing how much impact minor usability improvements can have for even a kernel hacker / developer like me.

Here’s hoping the future of Linux is even brighter, and that we’ll see amazing user interfaces and other improvements that make Ubuntu 10.10 look pathetic.

Rock on Canonical, rock on.

Atto

Advertisements
Categories: Uncategorized Tags: , , ,

Array map in C

October 16, 2010 4 comments

Last year, I got “The Ruby Way” (link) as a gift to myself. I’m not a major Ruby freak, but there are some cool things about it and I really enjoy Ruby in general.

As I read my way through the book, I remember reading about array map. Array map is cool, it let’s you do things like

my_strings.map {|s| s.strip! }

Which is roughly equivalent to

new_arr = []
my_strings.each {|s| new_arr.append(s.strip) }

Of course, this is kindof a stupid example and you can do MUCH more interesting things with Array#select or Array#reject – like write a one-liner to find all the phone numbers in an array that start with 351 or don’t hash to the same bucket, whatever. Anyway, I remember being really excited about array#map for some reason when I read that chapter. And whenever I get excited about something… weird things tend to happen. 🙂

See, I spend a lot of time writing programs in C. It’s a great language, and pretty much the only option in the kernel/filesystem/embedded world. So when I see a cool feature in another language (like Array map), I think “gee, wouldn’t it be awesome to have that in C.”

Being a frequent C coder, I do a lot of things with/to/because of arrays – and the two most common things I do with arrays are indexing and looping. Indexing is cool because it’s an O(1) operation, and that’s great for writing fast code that uses a lot of RAM. Looping, on the other hand… well, it’s usefulness depends on the problem at hand, but this is pretty common:

for(i = 0; i < count; i--);
   do_stuff_with(&my_array[i]);

Ten bonus points if you can spot the subtle bugs I put into this trivial for loop. Hint #1: there are three of them. Hint #2: the program (or kernel/firmware/driver) will not do anything useful. Beyond the obvious problems with this code (and how easy it is to accidentally slip in the extra semicolon), writing for loops gets really tedious and old sometimes.

So I keep thinking that it’d be neat to write a C library to implement Array map, select, reject. But then I start thinking about the code. To do this properly, you could use macros, something like

#define ARRAY_MAP(arr, size, func)                       \
        for(int i=0; i<(size); i++) (func)(arr[i]);
.
.
my_arr = malloc(sizeof(u32)*10);
memcpy(my_arr, arr1, sizeof(u32)*10);
ARRAY_MAP(my_arr, 10, do_stuff);

Well, that looks like junk and doesn’t really do much. You could implement it with callbacks to avoid the evils of macros, but that doesn’t help you much either. You still have to handle memory allocation, deallocation, type safety, and in the end the code doesn’t look any simpler.

Not to mention, for anything really high performance (filesystems, OSes, etc) you generally want to avoid looping over arrays in general – the Linux kernel now has a native hash table and circular buffer (among other fun data types). If performance is critical, use a better/faster/cooler algorithm and a more appropriate data type.

So I’m back to square one, array map in C is pointless. If you don’t care about runtime, just use arrays and loops, or use Python or Ruby.

But array map/select/reject is so cool… wouldn’t it be neat in C?

infinite_loop:
   printk(KERN_ERR "/me wants array_map in C");
   goto infinite_loop;

Best,

Atto

Categories: Uncategorized Tags: , , , ,

Simple Recursion

October 2, 2010 1 comment

I started writing this post last week, then an update to the wordpress app crashed and I lost the draft. With any luck, this post will be better than last week’s post would’ve been 🙂

A few weeks back, there was an article or two posted to digg/reddit/slashdot about recursion. The basic bottom line was something to the effect that 90% of programmers fail at simple recursion, which is both surprising and expected.

Surprising, because simple recursion really is… simple recursion. Most coders have seen the infamous Fibonacci series, and the (pseudo) code is quite simple:

def fib(n):
   if n == 1 or n == 0:
      return 1
   else:
      return fib(n-1) + fib(n-2)

You have a simple basis case (two cases, n is one or zero) to terminate the recursion, and if the inputs are not trivial to compute then you break the problem down into smaller problems and “recurse.” in the fibonacci example above, it’s pretty simple code to compute a simple numeric series… So it surprises me that coders can/do routinely fumble on this exact problem. I have personally seen multiple people fail this question in a interview with significant prompting. So it shouldn’t surprise me, but it does.

Now some people will argue with me and say the Fibonacci series is not a good question because it’s too (basic, academic, fill in the blank). And generally speaking, they’re correct – the Fibonacci series is a pretty basic, boring problem which is solvable with simple, basic code. So I am definitely interested in more complex, more advanced code which tackles more complex problems (merge sort anyone?). However someone who doesn’t get the Fibonacci series (which is a classic recursion example) is very unlikely to ace more challenging questions.

At this point, I have several other thoughts about recursion – non-trivial recursion is, not surprisingly, non-trivial; and I’d like to give some of the sorting algorithms a decent write-up. But for now I think I’ll keep it short and to the point:

Recursion can be elegant, fun, and simple. We should all spend a little more time recursing.

🙂

Categories: Uncategorized Tags: , ,