Layered C Library
Posted: Tue Jul 20, 2010 12:50 pm
I made an early decision when moving to userspace to have two layers to my C library. There is a lower layer, which contains nothing confirming to the standard, and doesn't use any functions from the upper layer, but has all of the OS-specific stuff, like file descriptors and IPC. The upper layer is just a normal C library, stripped of as much OS-specific stuff as possible. The problem is, I've been running into some issues with this separation.
First, both layers need access to the heap (in fact, the lower layer needs _another_ heap for persistent data, which is a huge mess in itself), so there are two separate heap APIs, one of which calls part of the other internally. This seems excessively pyramid-like, and makes all of the lower layer code unclear when it does memory allocation (it must use alloc_malloc(stdalloc, size) and alloc_free(stdalloc, ptr) instead of malloc(size) and free(ptr)).
Second, because all of the convenient (and safe, due to caching) I/O routines are in the higher layer, it is nearly impossible to debug the lower layer, even in the non-I/O areas, because nothing can be printed.
There are many other small dependency issues, as well as the added complexity of linking two libraries for basic functionality instead of one. The point is, there are too many cross-dependencies between the two libraries, because of the fact that the lower library needs platform independent stuff from the upper one, and the upper one's I/O routines need platform dependent stuff from the lower one.
What do you think I should do? Combining the two would allow me to remove a lot of redundant code and interface, but the whole idea at the beginning was to have the upper C library easily replaced by another C library, such as pdclib (after Solar finishes it in 2030 ), and that would remove the advantage. I could also try stratifying into three layers, the lowest for platform independent standard stuff (stdlib, stdint, etc.), the middle for platform dependent nonstandard stuff (read, write, send, etc.), and the highest for platform dependent standard stuff (stdio).
First, both layers need access to the heap (in fact, the lower layer needs _another_ heap for persistent data, which is a huge mess in itself), so there are two separate heap APIs, one of which calls part of the other internally. This seems excessively pyramid-like, and makes all of the lower layer code unclear when it does memory allocation (it must use alloc_malloc(stdalloc, size) and alloc_free(stdalloc, ptr) instead of malloc(size) and free(ptr)).
Second, because all of the convenient (and safe, due to caching) I/O routines are in the higher layer, it is nearly impossible to debug the lower layer, even in the non-I/O areas, because nothing can be printed.
There are many other small dependency issues, as well as the added complexity of linking two libraries for basic functionality instead of one. The point is, there are too many cross-dependencies between the two libraries, because of the fact that the lower library needs platform independent stuff from the upper one, and the upper one's I/O routines need platform dependent stuff from the lower one.
What do you think I should do? Combining the two would allow me to remove a lot of redundant code and interface, but the whole idea at the beginning was to have the upper C library easily replaced by another C library, such as pdclib (after Solar finishes it in 2030 ), and that would remove the advantage. I could also try stratifying into three layers, the lowest for platform independent standard stuff (stdlib, stdint, etc.), the middle for platform dependent nonstandard stuff (read, write, send, etc.), and the highest for platform dependent standard stuff (stdio).