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

Reply via email to