Statistics
| Branch: | Tag: | Revision:

root / test / lockperf.py @ e4d452b4

History | View | Annotate | Download (3.5 kB)

1
#!/usr/bin/python
2
#
3

    
4
# Copyright (C) 2011 Google Inc.
5
#
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.
10
#
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.
15
#
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
19
# 02110-1301, USA.
20

    
21

    
22
"""Script for testing lock performance"""
23

    
24
import os
25
import sys
26
import time
27
import optparse
28
import threading
29
import resource
30

    
31
from ganeti import locking
32

    
33

    
34
def ParseOptions():
35
  """Parses the command line options.
36

37
  In case of command line errors, it will show the usage and exit the
38
  program.
39

40
  @return: the options in a tuple
41

42
  """
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")
48

    
49
  (opts, args) = parser.parse_args()
50

    
51
  if opts.thread_count < 1:
52
    parser.error("Number of threads must be at least 1")
53

    
54
  return (opts, args)
55

    
56

    
57
class State:
58
  def __init__(self, thread_count):
59
    """Initializes this class.
60

61
    """
62
    self.verify = [False for _ in range(thread_count)]
63
    self.counts = [0 for _ in range(thread_count)]
64
    self.total_count = 0
65

    
66

    
67
def _Counter(lock, state, me):
68
  """Thread function for acquiring locks.
69

70
  """
71
  counts = state.counts
72
  verify = state.verify
73

    
74
  while True:
75
    lock.acquire()
76
    try:
77
      verify[me] = 1
78

    
79
      counts[me] += 1
80

    
81
      state.total_count += 1
82

    
83
      if state.total_count % 1000 == 0:
84
        sys.stdout.write(" %8d\r" % state.total_count)
85
        sys.stdout.flush()
86

    
87
      if sum(verify) != 1:
88
        print "Inconsistent state!"
89
        os._exit(1) # pylint: disable=W0212
90

    
91
      verify[me] = 0
92
    finally:
93
      lock.release()
94

    
95

    
96
def main():
97
  (opts, _) = ParseOptions()
98

    
99
  lock = locking.SharedLock("TestLock")
100

    
101
  state = State(opts.thread_count)
102

    
103
  lock.acquire(shared=0)
104
  try:
105
    for i in range(opts.thread_count):
106
      t = threading.Thread(target=_Counter, args=(lock, state, i))
107
      t.setDaemon(True)
108
      t.start()
109

    
110
    start = time.clock()
111
  finally:
112
    lock.release()
113

    
114
  while True:
115
    if (time.clock() - start) > opts.duration:
116
      break
117
    time.sleep(0.1)
118

    
119
  # Make sure we get a consistent view
120
  lock.acquire(shared=0)
121

    
122
  lock_cputime = time.clock() - start
123

    
124
  res = resource.getrusage(resource.RUSAGE_SELF)
125

    
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)))
131

    
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))
135
  print "Process:"
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)
139

    
140
  # Exit directly without attempting to clean up threads
141
  os._exit(0) # pylint: disable=W0212
142

    
143

    
144
if __name__ == "__main__":
145
  main()