Wednesday 2 May 2012

How to build a software bridge


- or how software engineering projects cannot be planned as regular engineering projects


Lets assume you are doing the typical engineering project - building a bridge. First, a large requirement process is done with the customer, to find the capacity, completion time, cost, etc. Then you plan, create a scale model, then bigger models, etc. All of these models and designs are iteratively more expensive and more detailed. On every step, the project may be scrapped because the project is found infeasible or too expensive - but the later the scrap, the larger the cost.

The reason these models are built up is because the actual physical step of building is so massive - which makes it very important to get the planning and design just right, since the difference between the good and bad design may mean a large monetary difference or even make the bridge fall down. And if a bad design choice shows that for example the capacity of the bridge is smaller than expected, fixing it might be very expensive and even mean that the bridge has to rebuilt.

Then lets assume we build the bridge as a software engineer would build it. The difference now is that building the bridge is free - or at least minuscule compared to the work cost of the engineer doing the design. So, you might want to build the bridge as noted earlier, doing testing, design, etc. the same way. However, with doing that you throw away a lot of the positive you get by using the fact that building the bridge is for free.

Modern software design principles exploit this principle. In the beginning of the project, the requirement process is shortened considerably. This lack of requirements are weighted by allowing new requirements to be added and existing requirements improved upon iteratively throughout the design process. When designing starts, a working bridge is built as soon as possible. It might fall down when more than two cars drive over it and it is held together with duct tape - but it is built.

And the bridge is built every time the design changes - down to every time a beam is added somewhere. And not only that, we build many bridges, and run different types of cars through them, we try to cut a cable and see what happens, maybe let the occasional asteriod hit it and see if it survives. And if one of the astroid tests suddenly fails when we change the design, we revert the design change, fix it and see if at least one of the cables hold on that asteriod impact.

Another exploitation that the free cost of building has is that the customer can try out the bridge while the design is still underway. The customer may find that the original requirement did not allow for buses, and that is improved upon. This requirement was something that the customer always intended - but when they got one of the early bridges, they tried to drive a bus across it and it falls down. As intended by the engineer ("it was never meant to do that!"), but expected by the customer. The change to the design might minimal, but the change in customer happiness is major.

The customer may also find that a new rail line has to be added beneath the car lane. This is something new that was not know when starting the project, and both the customer and engineer acknowledges this. This requires a major design change - but this is possible to do, even after the bridge was considered done, since we can simply tear the bridge down and set up a new one.

All this is not news - software used in Space Shuttle used iterative software development. And as all with all knowledge, a new generation rediscovered this and made it their own. But still companies are planning features years ahead of time, using methods that are geared against regular engineering, and not towards software engineering. It is used because it is known, it is simple, and it gives the manager much knowledge of what is happening. Using iterative methods means using methods that means more interaction, both from customers and management. But the rewards returned is definitely much higher than the work invested.

Sunday 15 April 2012

Using offsetof to implement linked lists

offsetof is a cute litte feature in C. What the function gives is the offset that a member has in a struct. Assume we have the given struct:

typedef struct {
   int a;
   char c;
   int b;
} s;
Offsetof would return something like this on fairly normal hardware:


offsetof(s, a); /*0 */
offsetof(s, c); /*4 */
offsetof(s, b); /*8 - no, not 5, more about that later... */
So what can this be used for? Well, a quite common use is for linked lists. A doublylinked list will often be written with two structures:



typedef struct link_t {
    struct link *next_link;
    struct link *prev_link;
} link;

typedef struct list_t {
    struct link *first_link;
    struct link *last_link;
}
Then, any structure that wants to be in a link list adds the link structure as a member:


typedef struct interesting_data {
    link_t link;
    int data;
} interesting_data;
To insert into a linked list, we then use a macro.



#define LIST_INSERT_BACK(list, link, member)\
do {\
    char *p = (char*)link;\
    link_t *l = (link_t*)((char*)link) + offsetof(typeof(link), member));\
    private_insert_back_link(list, l);\
}\ while(0)

#define LIST_GET_BACK(list, link_type, member)\
\ (link_type*) private_get_back_link(list, offsetof(link_type, member));


There are of course quite a few macros needed (to traverse the list, etc.), but they are all based on using offsetof to find the offset of the list member.

Tuesday 10 April 2012

Sizeof

So, this is the first of hopefully many mini-guides on how to do cool stuff in C...

You might usually use sizeof like this:

int *a = malloc(sizeof(int));

But a for many little known fact about C is that sizeof will get the size of the resulting type the of the expression given as the argument. This means that this line will do the same thing as the previous line:

int *a = malloc(sizeof(*a));

Since the expression *a will result in an int, the size of that expression is an int.

I went too long as a C-programmer without knowing this little fact.

Tuesday 21 February 2012

Waiting for Raspberry Pi...

I am currently waiting in eager anticipation for the Raspberry Pi - a small low-cost ARM computer. It costs $35. Yes, $35 dollar, for a fullfledged computer that can do 1080p video decoding as well as doing OpenGL ES.

I have a few plans for this computer - a computer that had the same specs as my computer 10 years ago, but will use a 100th of both volume and power.

Too bad they did not do like other dessert-based platforms and stick an Exynos chip in there, though.