Light-weight user level non-preemptive multi-threading library for GNU environment
##Features
- lwt provides similar APIs to Pthreads (POSIX Threading) that allow multi-threading programming, including operations of creating, joining, dying and etc
- The threads of lwt are user level threads, which have far lower overhead of context switching than Pthreads, however, they're blocking threads
- Inspired by Google's Go programming language, lwt provides similar mechanism of Go's channel for communicating between threads
- Buffered channels are supported for asynchronous communication, and channels can be sent through channel for bidirectional message passing
##APIs
###thread-related data structures
struct lwt_tcb {}
defines a TCB, which is short for thread control block, similar to PCB (process control block). It stores necessary information of a thread, when performing a thread switching, the data of current thread will be saved into corresponding TCB of current thread, and data of next thread will be restored from the TCB of next thread, if exists.*lwt_t
is a pointer tostruct lwt_tcb {}
to provide some easier operations- By maintaning a run queue (linked list) of
struct lwt_tcb {}
s, the library can perform possible operations easily by manipulating thesestruct lwt_tcb {}
s
###thread-related functions
int lwt_id(lwt_t)
takes in a pointer oflwt_tcb
, returns the ID of that threadlwt_t lwt_current(void)
returns the currently running thread, which is maintained by a global variablelwt_t lwt_create(lwt_fn_t, void*)
takes in two parameters: first one is a function pointer that denotes which function the newly created thread will execute, the second one passes in a value to that function. It returns a pointer to this newly created threadvoid *lwt_join(lwt_t)
receives a thread that to be joined, and blocking current thread until the execution of that thread is finished, and then returns avoid *
value from that thread. Notice that only parent thread can join their children thread, of zombie threads may exist in systemvoid lwt_die(void *)
can only be executed in threads to die themselves, it passes in avoid *
variable, which later will be returned from alwt_join()
function that performed on this threadint lwt_yield(lwt_t)
is for thread switching, suspends current thread and saves the content of current thread ot itsstruct lwt_tcb {}
, then continue the execution of destination thread by restoring the data of destination thread from its correspondingstruct lwt_tcb {}
###channel-related data structures
struct lwt_channel {}
defines the data structure of channel, which is used for message passing between/among threads. Each channel can be set up for multi senders but only one receiver.*lwt_chan_t
is the pointer that points tostruct lwt_channel {}
struct clist_head {}
is a linked list of senders of a channel, it is actually the head of the linked list, all the senders are chained by a memberstruct clist_head *next
of this structure.struct slist_head {}
is also the member ofstruct lwt_channel {}
, as introduced before, denoting the sender(s) of a channel
###channel-related functions
lwt_chan_t lwt_chan(int sz)
creates a channel (by mallocing space and define the data structures inside) referenced by the return value. The thread that creates the channel is the receiver of this channel. The parameter says the buffer size of the channel, if size is larger than 1, asyncrounous message passing is supportedvoid lwt_chan_deref(lwt_chan_t)
inspired by the reference counting system of Apple's Objective-C, used to deallocate a channel only if no thread still have reference to this channelint lwt_snd(lwt_chan_t, void *)
regards the second parameter as data, and send it to the channel denotes at first parameter.void *lwt_rcv(lwt_chan_t)
receives the datavoid *
from a channelint lwt_snd_chan(lwt_chan_t, lwt_chan_t)
is similar tovoid lwt_snd(lwt_chan_t, void *
, the only difference is this function sends another channel through a channel. It's very useful if you're to implemente bidirectional communicationlwt_chan_t lwt_rcv_chan(lwt_chan_t)
receives a channel from a channel
##Usage and Examples
main.c
contains examples about how to use the APIs- After cloned this repository into your local directory, use
$make
to copmile and link the project - Then you'll get a executable file named
main
, run it by$./main
to get some print out overhead measured by a inline assembly instruction rdtsc - Tested through the compiler
gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
##Authors