[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] xend: Add a multi-reader-single-writer lock implementation
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1225880539 0 # Node ID 484cf12ba667a3d2077bda3df24177ace78ff3fe # Parent 4bfc67b09e9c4bf99adfd6623cb66945c1b661cf xend: Add a multi-reader-single-writer lock implementation This patch adds a reader-writer lock primitive to xend since python does not provide it by default. The implementation is based on a condition variable. Some test code is appended at the end of the file. Signed-off-by: Stefan Berger <stefanb@xxxxxxxxxx> --- tools/python/xen/util/rwlock.py | 137 ++++++++++++++++++++++++++++++++++++++++ 1 files changed, 137 insertions(+) diff -r 4bfc67b09e9c -r 484cf12ba667 tools/python/xen/util/rwlock.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/python/xen/util/rwlock.py Wed Nov 05 10:22:19 2008 +0000 @@ -0,0 +1,137 @@ +""" Reader-writer lock implementation based on a condition variable """ + +#============================================================================ +# This library is free software; you can redistribute it and/or +# modify it under the terms of version 2.1 of the GNU Lesser General Public +# License as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +#============================================================================ +# Copyright (C) 2008 International Business Machines Corp. +# Author: Stefan Berger <stefanb@xxxxxxxxxx> +#============================================================================ + +from threading import Condition + +class RWLock: + + RWLOCK_STATE_WRITER = -1 + RWLOCK_STATE_UNUSED = 0 + + def __init__(self): + self.__condition = Condition() + self.__state = RWLock.RWLOCK_STATE_UNUSED + self.__blocked_writers = 0 + + def acquire_reader(self): + self.__condition.acquire() + while True: + if self.__state == RWLock.RWLOCK_STATE_WRITER: + self.__condition.wait() + else: + break + self.__state += 1 + self.__condition.release() + + def acquire_writer(self): + self.__condition.acquire() + self.__acquire_writer(RWLock.RWLOCK_STATE_UNUSED) + self.__condition.release() + + def __acquire_writer(self, wait_for_state): + while True: + if self.__state == wait_for_state: + self.__state = RWLock.RWLOCK_STATE_WRITER + break + else: + self.__blocked_writers += 1 + self.__condition.wait() + self.__blocked_writers -= 1 + + def release(self): + self.__condition.acquire() + if self.__state == RWLock.RWLOCK_STATE_WRITER: + self.__state = RWLock.RWLOCK_STATE_UNUSED + elif self.__state == RWLock.RWLOCK_STATE_UNUSED: + assert False, 'Lock not in use.' + else: + self.__state -= 1 + self.__condition.notifyAll() + self.__condition.release() + + +if __name__ == '__main__': + from threading import Thread + from time import sleep + + rwlock = RWLock() + + class Base(Thread): + def __init__(self, name, timeout): + self.name = name + self.timeout = timeout + Thread.__init__(self) + + class Reader(Base): + def __init__(self, name = 'Reader', timeout = 10): + Base.__init__(self, name, timeout) + + def run(self): + print '%s begin' % self.name + rwlock.acquire_reader() + print '%s acquired' % self.name + sleep(self.timeout) + rwlock.release() + print '%s end' % self.name + + class ReaderTwice(Base): + def __init__(self, name = 'Reader', timeout = 10): + Base.__init__(self, name, timeout) + + def run(self): + print '%s begin' % self.name + rwlock.acquire_reader() + print '%s acquired once' % self.name + sleep(self.timeout) + rwlock.acquire_reader() + print '%s acquired twice' % self.name + sleep(self.timeout) + rwlock.release() + rwlock.release() + print '%s end' % self.name + + class Writer(Base): + def __init__(self, name = 'Writer', timeout = 10): + Base.__init__(self, name, timeout) + + def run(self): + print '%s begin' % self.name + rwlock.acquire_writer() + print '%s acquired' % self.name + sleep(self.timeout) + rwlock.release() + print '%s end' % self.name + + def run_test(threadlist, msg): + print msg + for t in threadlist: + t.start() + sleep(1) + for t in threads: + t.join() + print 'Done\n\n' + + threads = [] + threads.append( Reader('R1', 4) ) + threads.append( Reader('R2', 4) ) + threads.append( Writer('W1', 4) ) + threads.append( Reader('R3', 4) ) + run_test(threads, + 'Test: readers may bypass blocked writers') _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |