I have a well defined list of things that i hate. Pretty colourful list, with
such things as 4strokes, Java, Multithreading etc etc. It wasn't long before i
noticed a strange "co-incidence": I know jackshit about most of the subjects in
that list. So that pointed to a rather unsettling reason as to why
most of the items figured in the list in the first place. So i decided to be
more fair, and for a start, have been spending time trying to read up on valves, valvetrains, tappets, timing chains, and all that shit. And rather unexpectedly,
i ended up in a three day Multithreading training last week.
It was a nice training, though i'm not completely reformed or anything. But it
did leave me with a strong itch to write a threading library myself. It was an
interesting experience indeed. So finally i ended up with a User Level thread
library, implemented though SIGALRMs and the Solaris context routines. I have
put it over here.
It offers the usual set of routines: thread creation and manipulation functions,
and routines for mutexes, semaphores, condition variables, and barriers.
Having just the usual set seemed boring, so i have added a rather wierd feature:
the user can register a callback function, which will be called during (just before, actually) each context switch. The function will be passed two pointer
arguments by the thread library: pointer to the id of the outgoing thread, and
to that of the incoming thread. So a user can actually manipulate and override
the "stock" scheduling logic by modifying the incoming thread id.
Another use would be along, say, monitoring lines. Say there is memory corruption
happening. Say under load. You don't know which thread is doing it. Maybe a
third party plugin is responsible. In such cases, you can register a function
which will keep monitoring the affected memory region. The moment corruption
happens, it can print out the outgoing thread id - the culprit - and say do an
abort.
The signal stack is an issue right now and should be fixed. Now there is only
one signal stack shared across threads, and it is not a good idea at all. One
thread can get scheduled out, then more interrupts come in, the signal stack
gets all "altered", and when that earlier thread gets scheduled back in, it's
gonna find a corrupted stack. Thinking of providing a separate (small) signal
stack to each thread, on which the SIGALRMs will be handled. That way, a thread
can be safely scheduled out while in "thread land", and safely scheduled back
in, later.
I built/tested it on Solaris 2.6 as well as 8. Didn't bother with Solaris 10 because
i would need to fix the makecontext() usage first. So right now it builds on
10, but crashes.
Next step is to fix some bugs and race conditions. And then the plan is to
upgrade the whole thing by bringing in LWP support, and hence move to an
M x N threading model.