Tools/ChangeLog

 12012-06-18 Dirk Pranke <dpranke@chromium.org>
 2
 3 NRWT should not take memory used as disk cache into account when deciding how many processes to launch
 4 https://bugs.webkit.org/show_bug.cgi?id=81379
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 The 'free memory' calculation we were running on the mac seemed
 9 to underestimate how many children we can run in parallel, and
 10 it was complex. This patch replaces that calculation with a
 11 simpler one that reserves 2GB for overhead and assumes 256MB per
 12 DRT/WTR, so if we had 4GB of RAM we can run up to 8 DRTs.
 13
 14 Also, there was a bug where we were truncating the memory
 15 installed on the machine to 4GB by casting to an int instead of
 16 a long; this was probably the source of some of the earlier
 17 problems when using total memory.
 18
 19 This patch also removes the no-longer-needed restrictions on the
 20 number of workers on beefy Lion boxes for both Apple Mac and Chromium
 21 Mac; we should now use all of the cores by default.
 22
 23 The memory calculations have only been implemented on the mac;
 24 having the calculation in base.default_child_processes() was IMO
 25 misleading, and so this patch also moves the computation into
 26 the MacPort. I have not heard of the # of workers being an issue
 27 on any other ports, so this should be fine.
 28
 29 * Scripts/webkitpy/common/system/platforminfo.py:
 30 (PlatformInfo.display_name):
 31 (PlatformInfo.total_bytes_memory):
 32 (PlatformInfo._win_version_tuple_from_cmd):
 33 * Scripts/webkitpy/common/system/platforminfo_unittest.py:
 34 (TestPlatformInfo.test_total_bytes_memory):
 35 * Scripts/webkitpy/layout_tests/port/base.py:
 36 (Port.default_child_processes):
 37 * Scripts/webkitpy/layout_tests/port/chromium_mac.py:
 38 (ChromiumMacPort.operating_system):
 39 * Scripts/webkitpy/layout_tests/port/mac.py:
 40 (MacPort.default_child_processes):
 41
1422012-06-18 Csaba Osztrogonác <ossy@webkit.org>
243
344 REGRESSION(r100558): NRWT should work without SVN or GIT

Tools/Scripts/webkitpy/common/system/platforminfo.py

@@class PlatformInfo(object):
8181 # Windows-2008ServerR2-6.1.7600
8282 return self._platform_module.platform()
8383
84  def free_bytes_memory(self):
85  if self.is_mac():
86  vm_stat_output = self._executive.run_command(["vm_stat"])
87  free_bytes = self._compute_bytes_from_vm_stat_output("Pages free", vm_stat_output)
88  # Per https://bugs.webkit.org/show_bug.cgi?id=74650 include inactive memory since the OS is lazy about freeing memory.
89  free_bytes += self._compute_bytes_from_vm_stat_output("Pages inactive", vm_stat_output)
90  return free_bytes
91  return None
92 
9384 def total_bytes_memory(self):
9485 if self.is_mac():
95  return int(self._executive.run_command(["sysctl", "-n", "hw.memsize"]))
 86 return long(self._executive.run_command(["sysctl", "-n", "hw.memsize"]))
9687 return None
9788
9889 def _determine_os_name(self, sys_platform):

@@class PlatformInfo(object):
141132 match_object = re.search(r'(?P<major>\d)\.(?P<minor>\d)\.(?P<build>\d+)', ver_output)
142133 assert match_object, 'cmd returned an unexpected version string: ' + ver_output
143134 return tuple(map(int, match_object.groups()))
144 
145  def _compute_bytes_from_vm_stat_output(self, label_text, vm_stat_output):
146  page_size_match = re.search(r"page size of (\d+) bytes", vm_stat_output)
147  free_pages_match = re.search(r"%s:\s+(\d+)." % label_text, vm_stat_output)
148 
149  # Fail hard if vmstat's output isn't what we expect.
150  assert(page_size_match and free_pages_match)
151 
152  free_page_count = int(free_pages_match.group(1))
153  page_size = int(page_size_match.group(1))
154  return free_page_count * page_size

Tools/Scripts/webkitpy/common/system/platforminfo_unittest.py

@@class TestPlatformInfo(unittest.TestCase):
180180 info = self.make_info(fake_sys('freebsd9'))
181181 self.assertEquals(info.total_bytes_memory(), None)
182182
183  def test_free_bytes_memory(self):
184  vmstat_output = ("Mach Virtual Memory Statistics: (page size of 4096 bytes)\n"
185  "Pages free: 1.\n"
186  "Pages inactive: 1.\n")
187  info = self.make_info(fake_sys('darwin'), fake_platform('10.6.3'), fake_executive(vmstat_output))
188  self.assertEquals(info.free_bytes_memory(), 8192)
189 
190  info = self.make_info(fake_sys('win32', tuple([6, 1, 7600])))
191  self.assertEquals(info.free_bytes_memory(), None)
192 
193  info = self.make_info(fake_sys('linux2'))
194  self.assertEquals(info.free_bytes_memory(), None)
195 
196  info = self.make_info(fake_sys('freebsd9'))
197  self.assertEquals(info.free_bytes_memory(), None)
198 
199183
200184if __name__ == '__main__':
201185 unittest.main()

Tools/Scripts/webkitpy/layout_tests/port/base.py

@@class Port(object):
154154
155155 def default_child_processes(self):
156156 """Return the number of DumpRenderTree instances to use for this port."""
157  cpu_count = self._executive.cpu_count()
158  # Make sure we have enough ram to support that many instances:
159  free_memory = self.host.platform.free_bytes_memory()
160  if free_memory:
161  bytes_per_drt = 200 * 1024 * 1024 # Assume each DRT needs 200MB to run.
162  supportable_instances = max(free_memory / bytes_per_drt, 1) # Always use one process, even if we don't have space for it.
163  if supportable_instances < cpu_count:
164  # FIXME: The Printer isn't initialized when this is called, so using _log would just show an unitialized logger error.
165  print "This machine could support %s child processes, but only has enough memory for %s." % (cpu_count, supportable_instances)
166  return min(supportable_instances, cpu_count)
167  return cpu_count
 157 return self._executive.cpu_count()
168158
169159 def worker_startup_delay_secs(self):
170160 # FIXME: If we start workers up too quickly, DumpRenderTree appears

Tools/Scripts/webkitpy/layout_tests/port/chromium_mac.py

@@class ChromiumMacPort(chromium.ChromiumPort):
101101 def operating_system(self):
102102 return 'mac'
103103
104  def default_child_processes(self):
105  # FIXME: As a temporary workaround while we figure out what's going
106  # on with https://bugs.webkit.org/show_bug.cgi?id=83076, reduce by
107  # half the # of workers we run by default on bigger machines.
108  default_count = super(ChromiumMacPort, self).default_child_processes()
109  if default_count >= 8:
110  cpu_count = self._executive.cpu_count()
111  return max(1, min(default_count, int(cpu_count / 2)))
112  return default_count
113 
114104 #
115105 # PROTECTED METHODS
116106 #

Tools/Scripts/webkitpy/layout_tests/port/mac.py

@@class MacPort(ApplePort):
117117 return self._version == "lion"
118118
119119 def default_child_processes(self):
 120 # FIXME: The Printer isn't initialized when this is called, so using _log would just show an unitialized logger error.
 121
120122 if self.is_snowleopard():
121  _log.warn("Cannot run tests in parallel on Snow Leopard due to rdar://problem/10621525.")
 123 print >> sys.stderr, "Cannot run tests in parallel on Snow Leopard due to rdar://problem/10621525."
122124 return 1
123125
124  # FIXME: As a temporary workaround while we figure out what's going
125  # on with https://bugs.webkit.org/show_bug.cgi?id=83076, reduce by
126  # half the # of workers we run by default on bigger machines.
127126 default_count = super(MacPort, self).default_child_processes()
128  if default_count >= 8:
129  cpu_count = self._executive.cpu_count()
130  return max(1, min(default_count, int(cpu_count / 2)))
131  return default_count
 127
 128 # Make sure we have enough ram to support that many instances:
 129 total_memory = self.host.platform.total_bytes_memory()
 130 bytes_per_drt = 256 * 1024 * 1024 # Assume each DRT needs 256MB to run.
 131 overhead = 2048 * 1024 * 1024 # Assume we need 2GB free for the O/S
 132 supportable_instances = max((total_memory - overhead) / bytes_per_drt, 1) # Always use one process, even if we don't have space for it.
 133 if supportable_instances < default_count:
 134 print >> sys.stderr, "This machine could support %s child processes, but only has enough memory for %s." % (default_count, supportable_instances)
 135 return min(supportable_instances, default_count)
132136
133137 def _build_java_test_support(self):
134138 java_tests_path = self._filesystem.join(self.layout_tests_dir(), "java")