
from threading import Thread
from threading import RLock
from fastrlock.rlock import FastRLock as FLock


def lock_unlock(l):
    l.acquire()
    l.release()
    l.acquire()
    l.release()
    l.acquire()
    l.release()
    l.acquire()
    l.release()
    l.acquire()
    l.release()


def reentrant_lock_unlock(l):
    l.acquire()
    l.acquire()
    l.acquire()
    l.acquire()
    l.acquire()
    l.release()
    l.release()
    l.release()
    l.release()
    l.release()


def mixed_lock_unlock(l):
    l.acquire()
    l.release()
    l.acquire()
    l.acquire()
    l.release()
    l.acquire()
    l.release()
    l.acquire()
    l.release()
    l.release()


def context_manager(l):
    with l: pass
    with l:
        with l:
            with l: pass
            with l: pass
        with l:
            with l: pass
        with l:
            with l: pass
            with l: pass
    with l: pass
    with l:
        with l:
            with l: pass
            with l: pass
            with l:
                with l: pass
    with l: pass


def lock_unlock_nonblocking(l):
    if l.acquire(False):
        l.release()
    if l.acquire(False):
        l.release()
    if l.acquire(False):
        l.release()
    if l.acquire(False):
        l.release()
    if l.acquire(False):
        l.release()


def threaded(l, test_func, tcount=10):
    threads = [ Thread(target=test_func, args=(l,)) for _ in range(tcount) ]
    for thread in threads:
        thread.start()
    for thread in threads:
        thread.join()


if __name__ == '__main__':
    functions = [
        lock_unlock,
        reentrant_lock_unlock,
        mixed_lock_unlock,
        lock_unlock_nonblocking,
        context_manager,
        ]

    import sys
    from timeit import Timer
    from functools import partial

    repeat_count = 100000
    repeat_count_t = 1000

    rlock, flock = ('threading.RLock', RLock()), ('FastRLock', FLock())
    locks = []
    args = sys.argv[1:]
    if 'rlock' in args:
        locks.append(rlock)
    if 'flock' in args:
        locks.append(flock)
    if not locks:
        locks = [rlock, flock]
    for _ in range(args.count('quick')):
        repeat_count = max(10, repeat_count // 100)
        repeat_count_t = max(5, repeat_count_t // 10)

    for name, lock in locks:
        print('Testing %s' % name)
        print("sequential (x%d):" % repeat_count)
        for function in functions:
            timer = Timer(partial(function, lock))
            print('%-25s: %9.2f msec' % (function.__name__, max(timer.repeat(repeat=4, number=repeat_count)) * 1000.0))

        print("threaded 10T (x%d):" % repeat_count_t)
        for function in functions:
            timer = Timer(partial(threaded, lock, function))
            print('%-25s: %9.2f msec' % (function.__name__, max(timer.repeat(repeat=4, number=repeat_count_t)) * 1000.0))

@@ -1720,16 +1720,37 @@
      %5D%0A%0A
+    import fastrlock%0A
     impo
@@ -1919,16 +1919,51 @@
  RLock()
+, %22%25d.%25d.%25d%22 %25 sys.version_info%5B:3%5D
 ), ('Fas
@@ -1978,16 +1978,39 @@
  FLock()
+, fastrlock.__version__
 )%0A    lo
@@ -2361,16 +2361,25 @@
 me, lock
+, version
  in lock
@@ -2410,17 +2410,34 @@
 g %25s
+ (%25s)
 ' %25 
+(
 name
-)
+, version))%0A
 %0A   

Print tested versions in benchmark.