4 # Copyright (C) 2011 Google Inc.
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful, but
12 # WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 # General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 """Script for testing lock performance"""
31 from ganeti import locking
35 """Parses the command line options.
37 In case of command line errors, it will show the usage and exit the
40 @return: the options in a tuple
43 parser = optparse.OptionParser()
44 parser.add_option("-t", dest="thread_count", default=1, type="int",
45 help="Number of threads", metavar="NUM")
46 parser.add_option("-d", dest="duration", default=5, type="float",
47 help="Duration", metavar="SECS")
49 (opts, args) = parser.parse_args()
51 if opts.thread_count < 1:
52 parser.error("Number of threads must be at least 1")
58 def __init__(self, thread_count):
59 """Initializes this class.
62 self.verify = [0 for _ in range(thread_count)]
63 self.counts = [0 for _ in range(thread_count)]
67 def _Counter(lock, state, me):
68 """Thread function for acquiring locks.
81 state.total_count += 1
83 if state.total_count % 1000 == 0:
84 sys.stdout.write(" %8d\r" % state.total_count)
88 print "Inconsistent state!"
89 os._exit(1) # pylint: disable=W0212
97 (opts, _) = ParseOptions()
99 lock = locking.SharedLock("TestLock")
101 state = State(opts.thread_count)
103 lock.acquire(shared=0)
105 for i in range(opts.thread_count):
106 t = threading.Thread(target=_Counter, args=(lock, state, i))
115 if (time.clock() - start) > opts.duration:
119 # Make sure we get a consistent view
120 lock.acquire(shared=0)
122 lock_cputime = time.clock() - start
124 res = resource.getrusage(resource.RUSAGE_SELF)
126 print "Total number of acquisitions: %s" % state.total_count
127 print "Per-thread acquisitions:"
128 for (i, count) in enumerate(state.counts):
129 print (" Thread %s: %d (%0.1f%%)" %
130 (i, count, (100.0 * count / state.total_count)))
132 print "Benchmark CPU time: %0.3fs" % lock_cputime
133 print ("Average time per lock acquisition: %0.5fms" %
134 (1000.0 * lock_cputime / state.total_count))
136 print " User time: %0.3fs" % res.ru_utime
137 print " System time: %0.3fs" % res.ru_stime
138 print " Total time: %0.3fs" % (res.ru_utime + res.ru_stime)
140 # Exit directly without attempting to clean up threads
141 os._exit(0) # pylint: disable=W0212
144 if __name__ == "__main__":