On Tue, May 12, 2009 at 9:16 AM, Eric Day <[email protected]> wrote: > On Mon, May 11, 2009 at 05:40:16PM +0800, Biping MENG wrote: > > So, the advantage of letting drizzled to do context switch briefly > lies on > > two facts: > > - Drizzled has more knowledge to decide when and where to switch > context > > so as to avoid unnecessary switches. > > Yup, more useful context in drizzled than letting the kernel decide > when. > > > - We are able to do it at lower overhead (both CPU time and memory). > > We should make a user level thread to yield, when it gets blocked on > > locks, condition vars or I/Os. So we should use pthread_mutex_trylock > on > > mutex, pthread_cond_timedwait on condition vars and non-block socket > on > > I/Os. > > Well, maybe not everywhere. Initially doing it on socket I/O would > be a big win, and then eventually on disk I/O. We may need to on the > mutexes to prevent deadlocks (depending on the lock), but most mutexes > should be pretty short lived, so we may want to always switch on those.
Actually one user level thread corresponds to one session and many user level threads may run on one kernel thread. So if we switch between user-level threads, mutexes shared by sessions(equal to user-level threads) may cause a deadlock by invoking yield(). Brain also reminded me of this on the IRC. I'm thinking about the relation of these two levels of threads and locks on these two levels. I thought a simple way of avoiding deadlock is to alway require locks sequentially. To keep this principle is an easy way to avoid deadlock. I may need some time to check through the locks and build up a sequence on them. I guess we have to set up a strategy to arrange user-level threads onto kernel thread. I'm thinking of these done in the following ways: A. All kernel threads share one pair of queues of sessions(mixed up with newly connected sessions and switched out sessions by calling yield()). Sessions that have just called yield() must have been blocked for some reason, so should be pushed back into the queue, and may wait for long enough to be swapped in. B. Each kernel thread have its own pair of queues of sessions. The main thread is responsible for assigning newly connected sessions to these queues so as to keep the number of sessions in the queues as even as possible. This may avoid some lock races on access to the queue between kernel threads. Just as in the current implementation, sessions are separated into two groups, that is need_processing and wait_for_io, so queues are always in pairs. Maybe sessions_wait_for_io would rather be sessions_blocked. We can monitor FDs by using libevent when they are ready to read or write. But how could we monitor on mutexes to tell when they are unlocked? > > And add a yield(Session*) entry to the scheduler interface so > that > > the session running on a user level thread could yield when failed to > get > > a lock or read data from a socket fd. Changing the socket to > non-blocking > > would be a big work as we have to modify the current I/O working mode. > > This shouldn't be too much work, since all the socket I/O code is > now abstracted and I'll be pluggin the new libdrizzle in shortly > (which is all non-blocking I/O). It's great to enjoy the power of abstraction:). -- Cheers. Biping MENG Natural Language Processing(NLP) Lab Dept. of Computer Science and Technology Nanjing University
_______________________________________________ Mailing list: https://launchpad.net/~drizzle-discuss Post to : [email protected] Unsubscribe : https://launchpad.net/~drizzle-discuss More help : https://help.launchpad.net/ListHelp

