Class inheritence in C
Submitted by marineam on Wed, 05/07/2008 - 21:43.For a while now I have been slowly developing a touchscreen music player to replace the stereo in my car. Although that concept should be fairly simple the project has turned into a bit of a playground for learning how to implement an X toolkit using nothing but C, XCB, and Cairo. One of the more recent legs this project has grown is an object oriented system for C which supports class inheritance and method overriding for use in my toolkit.
At this point I've got it almost the way I like it. Defining a class in a header looks something like this:
CLASS(mtk_widget, mtk_object)
int x, y, w, h;
struct mtk_window *window;
struct mtk_widget *parent;
cairo_surface_t *surface;
METHODS(mtk_widget, mtk_object, int x, int y, int w, int h)
void (*init)(mtk_widget_t *this, mtk_widget_t* parent);
void (*draw)(mtk_widget_t *this); /* children must implement this */
void (*update)(mtk_widget_t *this);
void (*mouse_press)(mtk_widget_t *this, int x, int y);
void (*mouse_release)(mtk_widget_t *this, int x, int y);
void (*mouse_move)(mtk_widget_t *this, int x, int y);
void (*set_geometry)(mtk_widget_t *this, int x, int y, int w, int h);
void (*set_parent)(mtk_widget_t *this, mtk_widget_t *parent);
END
This defines a new class named mtk_widget based on the base class mtk_object. The extra arguments to the METHODS macro are additional arguments for the object constructor.
To actually implement the class the corresponding C file will have something like this:
/* more methods up here */
static void set_parent(mtk_widget_t *this, mtk_widget_t *parent)
{
this->parent = parent;
}
mtk_widget_t* mtk_widget_new(size_t size, int x, int y, int w, int h)
{
mtk_widget_t* this = mtk_widget(mtk_object_new(size));
SET_CLASS(this, mtk_widget);
this->x = x;
this->y = y;
this->w = w;
this->h = h;
return this;
}
METHOD_TABLE_INIT(mtk_widget, mtk_object)
METHOD(init);
METHOD(draw);
METHOD(set_geometry);
METHOD(set_parent);
METHOD_TABLE_END
Methods can (and probably should) be static functions. The METHOD_TABLE_INIT macro defines the function _mtk_widget_class_init() to fill up a hidden structure named _mtk_widget_class which is the class virtual method table. Each object then has a pointer tucked away inside to its class's method table (set by the SET_CLASS macro). One thing that is a bit clunky about this is that the program must somehow call _mtk_widget_class_init() before the class is ever used. I would like to be able to do away with that by using GCC's constructor function attribute so it magically runs before main(). However the class hierarchy must be initialized in order but a way to order the constructors was not added until GCC 4.3. I'm using 4.1 on my system so that feature will have to wait for now.
Actually using objects looks something like this:
int main (int argc, char *argv[])
{
mtk_window_t *window;
mtk_widget_t *widget;
mtk_init();
window = new(mtk_window,640, 480);
widget = mtk_widget(new(mtk_text, 0, 0, 640, 480, "WHEE"));
call(window, mtk_container, add_widget, widget);
mtk_main();
mtk_cleanup();
return 0;
}
Pretty strait forward, call() is a bit weird though. It takes the arguments (object, class name that defined the method, method name, method arguments). I would like to be able to get rid of the class argument somehow (it is used to cast object to the correct type) but I haven't come up with a solution yet. I have a similar clunkyness with my super() macro for calling a parent class's method when doing method overriding.
That's pretty much it. As with the rest of this project it is a good example of making things more complicated than they need to be but it was an interesting challenge to put together.
The code for the above macros and base class can be found in this header and c file.
Gentoo, the OSL, and Xen
Submitted by marineam on Sat, 02/02/2008 - 22:23.Quite a few of the projects hosted at the OSU Open Source Lab are using Xen virtual machines. If you are associated with one of those projects you may be interested to know what exactly our current setup is and what my future plans for it are. If you are not currently hosted by us maybe you will be some day. :-)
Since last fall the I have been running a Xen cluster at the OSL which is slowly replacing our original independent Xen hosts. We currently host a total of 41 Xen virtual machines which include projects like Busybox, Inkscape, an OFTC IRC node, the Freenode website, the OLPC user support forums, and many others. Currently 17 of those are on the new cluster split between 3 of the 6 available host nodes. The other 24 virtual machines are still on two of our older independent Xen hosts.
The older Xen hosts are just boxes loaded with lots of disk and ram, with the virtual machines running off of the local disk space. The problem with this setup is that Xen and Linux kernel upgrades are incredibly difficult. Since the virtual machines cannot easily move to another host upgrading Xen requires taking an outage for all 8 to 12 virtual machines running on that host. To complicate matters Xen can be a bit troublesome to install/upgrade sometimes so it is not uncommon for such an upgrade to take much longer than expected. To improve this situation I built out our Xen cluster.
The cluster currently consists of 6 Xen hosts which are part of a 14 blade IBM Bladecetner that was donated to us by Intel. The 6 hosts each have 4GB of RAM and dual Pentium 4 processors and can typically run between 6 and 8 virtual machines depending on RAM and CPU needs. The remaining 8 blades will eventually be built out as more hosts but currently are waiting on RAM. (Anyone have a pile of 1GB PC2100 sticks laying around?) All of the disk space is hosted via iSCSI on a separate disk node. The current disk node is a Dell 2650 with 260GB of disk for virtual machines and is serving up that space with ietd since we don't have a hardware based iSCSI target card.
The good thing about this new setup is I can migrate virtual machines between host nodes on demand while they are running so I can easily upgrade the host nodes as needed. Maybe some day I will get better monitoring set up so I can move virtual machines around to balance CPU load but that's not planned for the near future. The bad thing is I still have a single point of failure with the single disk node. Also the disk node doesn't have very much disk space so we have nearly filled it up which is why the cluster is only running 17 virtual machines. So the setup is not perfect but it's a pretty good start using hardware that was either donated or we already had.
Down the road I want to replace the current disk node with two boxes replicating the data using DRBD and set up graceful fail-over between the two using heartbeat. The current plan is to upgrade the disk space on our mirror servers and use some of the old disk arrays for the Xen cluster. This will give us about 3TB total for 1.5TB of redundant disk space between the two disk nodes. That will give us enough space to move all of our existing virtual machines over to the cluster with room for 30-40 more for a total of 54-64. That won't quite fill up the Xen host nodes which can probably host 80-90 virtual machines while keeping one host node as a hot spare. It will be enough room for about a year and a half worth of growth and should enable us to provide great up time for the hosted projects. :-) Unfortunately with this plan the Xen upgrade is waiting on the mirror upgrade which is waiting on money to buy the new disks and I have no idea when that is going to happen. Hopefully something will pull though soon, the mirrors have been needing this upgrade for nearly a year now.
And how does Gentoo fit into all of this? All of the Xen and disk hosts run Gentoo and are managed by our central cfengine system. I have been maintaining the Xen packages for Gentoo to keep them in working order for use at the OSL and the whole setup seems to work pretty well now. Hopefully later today I'll have a chance to start rolling packages for Xen 3.1.3 and 3.2.0.
Waffles!
Submitted by marineam on Fri, 01/04/2008 - 06:35.By popular demand* here is my mom's pancake/waffle mix recipe. I'm not sure where it originally came from but it is damn tasty. Enjoy.
Mix: 3 1/2 C white flour Combine all ingredients, mixing 3 1/2 C whole wheat flour together to resemble fine meal. 1/2 C wheat germ 1/2 C soy flour Tip: To make life easy add the 1/2 C cornmeal oil last and mix in with a whisk 1 T+1 t salt or some sort of pastry blender. 3 T baking powder 1 T+1 t baking soda 1/2 C oil Pancakes: Waffles: 1 Cup mix Same as pancakes plus 2-3 Tbsp oil 1 egg 1 Cup buttermilk
*And by popular demand I mean Beth asked me, so I might as well post it here since I have to type it up anyway.
- Login to post comments
OSL Beer Fund
Submitted by marineam on Wed, 08/08/2007 - 07:35.So, here is a crazy idea that I actually got around to implementing: The OSL Beer Fund. As a sysadmin for the Open Source Lab I work with a lot of people via email and IRC from all over the world. As a student I don't exactly have much of a budget to travel to far off conferences to meet up with many of those people. So the idea is this: if you would like to help save our sanity or simply say thanks to one of us but can't meet up for beers in person why not contribute a couple bucks to our beer fund? In return we can even give your favorite server a little extra luvin'. Just contribute via paypal to beerfund_AT_osuosl.org.
Disclaimer:
The OSL Beer Fund is not associated with the OSU Open Source Lab in any official way. It just happens to have the email account 'beerfund' under the osuosl.org domain, by chance a random letter generator gave us the acronym 'OSL' to use as the fund's name, and somehow all beer purchased with the fund manages to go to students who work for the Open Source Lab (and who are of age of course). How that all worked out I don't know, we sure didn't plan it. ;-)
- Login to post comments