diff options
Diffstat (limited to 'doc')
-rw-r--r-- | doc/BOOST | 1 | ||||
-rw-r--r-- | doc/design-concepts.txt | 116 |
2 files changed, 117 insertions, 0 deletions
@@ -4,6 +4,7 @@ equivilant in Mowgli: dynamic_bitset -> mowgli_bitvector pool -> mowgli_memorypool smart_ptr -> mowgli_object + asio -> mowgli_eventloop, mowgli_vio Many boost libraries that are applicable to C have not yet been implemented. You can visit http://www.boost.org/libs/libraries.htm diff --git a/doc/design-concepts.txt b/doc/design-concepts.txt new file mode 100644 index 0000000..5d596bd --- /dev/null +++ b/doc/design-concepts.txt @@ -0,0 +1,116 @@ +Design concepts for Mowgli +-------------------------- + +1. Object orientation + +First and foremost, Mowgli is a base development framework that you can build +higher level development frameworks ontop of. To facilitate this in a way that +most people can understand, we use a somewhat LISP-like form of OO. + +What does this mean? + +In LISP, it is common for objects to be made up of smaller, more primitive +objects that help to facilitate the implementation of the object. What this +means is that, for example, we have mowgli_heap_t (which is a private object): + + struct mowgli_heap_ + { + unsigned int elem_size; + unsigned int mowgli_heap_elems; + unsigned int free_elems; + + unsigned int alloc_size; + + unsigned int flags; + + mowgli_list_t blocks; /* list of non-empty blocks */ + + mowgli_allocation_policy_t *allocator; + mowgli_boolean_t use_mmap; + + mowgli_mutex_t mutex; + + mowgli_block_t *empty_block; /* a single entirely free block, + * or NULL */ + }; + +This is an object which keeps state. It also depends on other objects, such as +allocation policies and lists. There is a need for a destructor, it has member +objects which have destructors, etc. + +C allows you to make a pointer out of anything -- block-level variables, for +example can be "dereferenced" using the & operator. This means that if the heap +above did not require initialization, you could just write something like: + + { + mowgli_heap_t heap; + void *ptr; + + ptr = mowgli_heap_alloc(&heap); + mowgli_heap_free(&heap, ptr); + } + +However, we have a need to initialize this object, so we provide a constructor +for it, mowgli_heap_create(). We also need to tear down the object +specifically, so we provide mowgli_heap_destroy(). + +While it is easy to provide a separate initializer function, we feel this would +be a bad idea for objects which keep state, because odds are likely the +destructor would not be called. There is also a stack memory limit -- which is +very small on embedded systems, where Mowgli is intended to be used. + +There is also the possibility that the library may depend on the reference +remaining past the time it was used, such as an internal dependency (caching, +for example). So we want to enforce that a destructor is called when needed, or +at least make sure we don't crash because the object is no longer on the stack. + +[Yes, I know you can put objects in BSS by making them 'static.' There is +limited space for BSS on many systems, so putting 100MB worth of objects there +is kind of insane and makes your program not look so great either.] + +2. Threads are evil. + +"The one-sentence answer is that humans are not smart enough to write + thread-safe code." + -- Rasmus Lerdorf, inventor of PHP + +While PHP itself is a disaster of a programming language (for reasons I am not +going to go into here), Rasmus Lerdorf is entirely correct in the above quote. +While Mowgli is itself thread-safe, we do not recommend using threads as they +promote inferior design patterns. There are better, safer ways to achieve +concurrency using helpers and work queues with message-passing. + +Mowgli's thread library implements a subset of a thread library. Specifically, +it implements the fastest possible mutex implementation, and global critical +sections ala a global lock. It does not implement anything else other than +that, except for maybe abstraction of TLS data in the future. But that TLS +support would just be to further advance Mowgli's thread-safety so that it is +more performant. + +Threads are a gigantic hack. Depending on what you want, there is usually +something better for any pattern which involves threads: + +Pattern: Threads which do work and then sleep for a long time. + +Answer: Use mowgli_timer_add() on an eventloop object. This allows you to +queue deferred work as a first-class citizen of your app's eventloop. + +Pattern: Multiple worker threads for I/O. + +Answer: Using concurrency in an I/O bound app is entirely pointless, but you +can pass FDs to a helper using IPC. Pass the FD and then pass instructions on +what to do with it. + +Pattern: Work that needs to be done concurrently. + +Answer: Helpers with message-passing and specific regions of memory shared +between helpers, ala mmap() or VirtualAlloc(). + +Pattern: Work that needs to be done cooperatively. + +Answer: Producer-consumer models can be implemented as first-class citizens +using the eventloop using pipes as a synchronization primitive. Alternatively, +use a coroutine library, such as the work-in-progress mowgli.coroutine. + +Pretty much anything you can do with threads, you can do better with something, +*anything* else. |