diff options
author | Chris Larson <chris_larson@mentor.com> | 2010-11-18 22:47:36 -0700 |
---|---|---|
committer | Richard Purdie <rpurdie@linux.intel.com> | 2011-01-04 14:46:43 +0000 |
commit | 7c9444e9a58438058ec577bd8c2e51820c98072d (patch) | |
tree | 55074d2c00afa924707bb5b5d30b22bc6688594d /bitbake/lib | |
parent | 95d2f56126d459b9e7f000d22ed7c1206d1a8f68 (diff) | |
download | poky-7c9444e9a58438058ec577bd8c2e51820c98072d.tar.gz |
cache: sync the cache file to disk in the background
This version uses a thread rather than a process, to avoid problems with
waitpid handling. This gives slightly less overall build time reduction than
the separate process for it did (this reduces a -c compile coreutils-native by
about 3 seconds, while the process reduced it by 7 seconds), however this time
is quite insignificant relative to a typical build.
The biggest issue with non-backgrounded syncing is the perceived delay before
work begins, and this resolves that without breaking anything, or so it seems.
(Bitbake rev: 5ab6c5c7b007b8c77c751582141afc07c183d672)
Signed-off-by: Chris Larson <chris_larson@mentor.com>
Signed-off-by: Richard Purdie <rpurdie@linux.intel.com>
Diffstat (limited to 'bitbake/lib')
-rw-r--r-- | bitbake/lib/bb/cooker.py | 31 | ||||
-rw-r--r-- | bitbake/lib/bb/event.py | 20 | ||||
-rw-r--r-- | bitbake/lib/bb/ui/knotty.py | 34 | ||||
-rw-r--r-- | bitbake/lib/bb/ui/uievent.py | 18 |
4 files changed, 60 insertions, 43 deletions
diff --git a/bitbake/lib/bb/cooker.py b/bitbake/lib/bb/cooker.py index 0143c149b8..ac9758d402 100644 --- a/bitbake/lib/bb/cooker.py +++ b/bitbake/lib/bb/cooker.py | |||
@@ -25,6 +25,7 @@ from __future__ import print_function | |||
25 | import sys, os, glob, os.path, re, time | 25 | import sys, os, glob, os.path, re, time |
26 | import logging | 26 | import logging |
27 | import sre_constants | 27 | import sre_constants |
28 | import threading | ||
28 | import multiprocessing | 29 | import multiprocessing |
29 | import signal | 30 | import signal |
30 | from cStringIO import StringIO | 31 | from cStringIO import StringIO |
@@ -983,6 +984,7 @@ class CookerParser(object): | |||
983 | # Internal data | 984 | # Internal data |
984 | self.filelist = filelist | 985 | self.filelist = filelist |
985 | self.cooker = cooker | 986 | self.cooker = cooker |
987 | self.cfgdata = cooker.configuration.data | ||
986 | 988 | ||
987 | # Accounting statistics | 989 | # Accounting statistics |
988 | self.parsed = 0 | 990 | self.parsed = 0 |
@@ -1006,7 +1008,6 @@ class CookerParser(object): | |||
1006 | self.result_queue = multiprocessing.Queue() | 1008 | self.result_queue = multiprocessing.Queue() |
1007 | 1009 | ||
1008 | self.fromcache = [] | 1010 | self.fromcache = [] |
1009 | cfgdata = self.cooker.configuration.data | ||
1010 | for filename in self.filelist: | 1011 | for filename in self.filelist: |
1011 | appends = self.cooker.get_file_appends(filename) | 1012 | appends = self.cooker.get_file_appends(filename) |
1012 | if not self.cooker.bb_cache.cacheValid(filename): | 1013 | if not self.cooker.bb_cache.cacheValid(filename): |
@@ -1021,13 +1022,13 @@ class CookerParser(object): | |||
1021 | output.put(infos) | 1022 | output.put(infos) |
1022 | 1023 | ||
1023 | self.processes = [] | 1024 | self.processes = [] |
1024 | num_processes = int(cfgdata.getVar("BB_NUMBER_PARSE_THREADS", True) or | 1025 | num_processes = int(self.cfgdata.getVar("BB_NUMBER_PARSE_THREADS", True) or |
1025 | multiprocessing.cpu_count()) | 1026 | multiprocessing.cpu_count()) |
1026 | for i in xrange(num_processes): | 1027 | for i in xrange(num_processes): |
1027 | process = multiprocessing.Process(target=worker, | 1028 | process = multiprocessing.Process(target=worker, |
1028 | args=(self.task_queue, | 1029 | args=(self.task_queue, |
1029 | self.result_queue, | 1030 | self.result_queue, |
1030 | cfgdata)) | 1031 | self.cfgdata)) |
1031 | process.start() | 1032 | process.start() |
1032 | self.processes.append(process) | 1033 | self.processes.append(process) |
1033 | 1034 | ||
@@ -1041,29 +1042,29 @@ class CookerParser(object): | |||
1041 | self.task_queue.close() | 1042 | self.task_queue.close() |
1042 | for process in self.processes: | 1043 | for process in self.processes: |
1043 | process.join() | 1044 | process.join() |
1044 | self.cooker.bb_cache.sync() | 1045 | threading.Thread(target=self.cooker.bb_cache.sync).start() |
1045 | bb.codeparser.parser_cache_save(self.cooker.configuration.data) | 1046 | threading.Thread(target=bb.codeparser.parser_cache_save(self.cooker.configuration.data)).start() |
1046 | if self.error > 0: | 1047 | if self.error > 0: |
1047 | raise ParsingErrorsFound() | 1048 | raise ParsingErrorsFound() |
1048 | 1049 | ||
1049 | def progress(self): | ||
1050 | bb.event.fire(bb.event.ParseProgress(self.cached, self.parsed, | ||
1051 | self.skipped, self.masked, | ||
1052 | self.virtuals, self.error, | ||
1053 | self.total), | ||
1054 | self.cooker.configuration.event_data) | ||
1055 | |||
1056 | def parse_next(self): | 1050 | def parse_next(self): |
1057 | cooker = self.cooker | 1051 | cooker = self.cooker |
1058 | if self.current >= self.total: | 1052 | if self.current >= self.total: |
1053 | event = bb.event.ParseCompleted(self.cached, self.parsed, | ||
1054 | self.skipped, self.masked, | ||
1055 | self.virtuals, self.error, | ||
1056 | self.total) | ||
1057 | bb.event.fire(event, self.cfgdata) | ||
1059 | self.shutdown() | 1058 | self.shutdown() |
1060 | return False | 1059 | return False |
1060 | elif self.current == 0: | ||
1061 | bb.event.fire(bb.event.ParseStarted(self.total, self.skipped, self.masked), | ||
1062 | self.cfgdata) | ||
1061 | 1063 | ||
1062 | try: | 1064 | try: |
1063 | if self.result_queue.empty() and self.fromcache: | 1065 | if self.result_queue.empty() and self.fromcache: |
1064 | filename, appends = self.fromcache.pop() | 1066 | filename, appends = self.fromcache.pop() |
1065 | _, infos = cooker.bb_cache.load(filename, appends, | 1067 | _, infos = cooker.bb_cache.load(filename, appends, self.cfgdata) |
1066 | self.cooker.configuration.data) | ||
1067 | parsed = False | 1068 | parsed = False |
1068 | else: | 1069 | else: |
1069 | infos = self.result_queue.get() | 1070 | infos = self.result_queue.get() |
@@ -1087,7 +1088,7 @@ class CookerParser(object): | |||
1087 | if info.skipped: | 1088 | if info.skipped: |
1088 | self.skipped += 1 | 1089 | self.skipped += 1 |
1089 | finally: | 1090 | finally: |
1090 | self.progress() | 1091 | bb.event.fire(bb.event.ParseProgress(self.current), self.cfgdata) |
1091 | 1092 | ||
1092 | self.current += 1 | 1093 | self.current += 1 |
1093 | return True | 1094 | return True |
diff --git a/bitbake/lib/bb/event.py b/bitbake/lib/bb/event.py index 5f292bccbc..5b0a183acd 100644 --- a/bitbake/lib/bb/event.py +++ b/bitbake/lib/bb/event.py | |||
@@ -296,10 +296,16 @@ class MultipleProviders(Event): | |||
296 | """ | 296 | """ |
297 | return self._candidates | 297 | return self._candidates |
298 | 298 | ||
299 | class ParseProgress(Event): | 299 | class ParseStarted(Event): |
300 | """ | 300 | """Recipe parsing for the runqueue has begun""" |
301 | Parsing Progress Event | 301 | def __init__(self, total, skipped, masked): |
302 | """ | 302 | Event.__init__(self) |
303 | self.total = total | ||
304 | self.skipped = skipped | ||
305 | self.masked = masked | ||
306 | |||
307 | class ParseCompleted(Event): | ||
308 | """Recipe parsing for the runqueue has completed""" | ||
303 | 309 | ||
304 | def __init__(self, cached, parsed, skipped, masked, virtuals, errors, total): | 310 | def __init__(self, cached, parsed, skipped, masked, virtuals, errors, total): |
305 | Event.__init__(self) | 311 | Event.__init__(self) |
@@ -312,6 +318,12 @@ class ParseProgress(Event): | |||
312 | self.sofar = cached + parsed | 318 | self.sofar = cached + parsed |
313 | self.total = total | 319 | self.total = total |
314 | 320 | ||
321 | class ParseProgress(Event): | ||
322 | """Recipe parsing progress""" | ||
323 | |||
324 | def __init__(self, current): | ||
325 | self.current = current | ||
326 | |||
315 | class DepTreeGenerated(Event): | 327 | class DepTreeGenerated(Event): |
316 | """ | 328 | """ |
317 | Event when a dependency tree has been generated | 329 | Event when a dependency tree has been generated |
diff --git a/bitbake/lib/bb/ui/knotty.py b/bitbake/lib/bb/ui/knotty.py index a34991bb68..326f164353 100644 --- a/bitbake/lib/bb/ui/knotty.py +++ b/bitbake/lib/bb/ui/knotty.py | |||
@@ -78,6 +78,7 @@ def init(server, eventHandler): | |||
78 | return 1 | 78 | return 1 |
79 | 79 | ||
80 | pbar = None | 80 | pbar = None |
81 | interactive = os.isatty(sys.stdout.fileno()) | ||
81 | shutdown = 0 | 82 | shutdown = 0 |
82 | return_value = 0 | 83 | return_value = 0 |
83 | while True: | 84 | while True: |
@@ -132,23 +133,26 @@ def init(server, eventHandler): | |||
132 | if isinstance(event, bb.build.TaskBase): | 133 | if isinstance(event, bb.build.TaskBase): |
133 | logger.info(event._message) | 134 | logger.info(event._message) |
134 | continue | 135 | continue |
136 | if isinstance(event, bb.event.ParseStarted): | ||
137 | if interactive: | ||
138 | pbar = progressbar.ProgressBar(widgets=widgets, | ||
139 | maxval=event.total).start() | ||
140 | else: | ||
141 | sys.stdout.write("Parsing recipes...") | ||
142 | sys.stdout.flush() | ||
143 | continue | ||
135 | if isinstance(event, bb.event.ParseProgress): | 144 | if isinstance(event, bb.event.ParseProgress): |
136 | current, total = event.sofar, event.total | 145 | if interactive: |
137 | if os.isatty(sys.stdout.fileno()): | 146 | pbar.update(event.current) |
138 | if not pbar: | 147 | continue |
139 | pbar = progressbar.ProgressBar(widgets=widgets, | 148 | if isinstance(event, bb.event.ParseCompleted): |
140 | maxval=total).start() | 149 | if interactive: |
141 | pbar.update(current) | 150 | pbar.update(event.total) |
142 | else: | 151 | else: |
143 | if current == 1: | 152 | sys.stdout.write("done.\n") |
144 | sys.stdout.write("Parsing .bb files, please wait...") | 153 | sys.stdout.flush() |
145 | sys.stdout.flush() | 154 | print(("\nParsing of %d .bb files complete (%d cached, %d parsed). %d targets, %d skipped, %d masked, %d errors." |
146 | if current == total: | 155 | % ( event.total, event.cached, event.parsed, event.virtuals, event.skipped, event.masked, event.errors))) |
147 | sys.stdout.write("done.") | ||
148 | sys.stdout.flush() | ||
149 | if current == total: | ||
150 | print(("\nParsing of %d .bb files complete (%d cached, %d parsed). %d targets, %d skipped, %d masked, %d errors." | ||
151 | % ( event.total, event.cached, event.parsed, event.virtuals, event.skipped, event.masked, event.errors))) | ||
152 | continue | 156 | continue |
153 | 157 | ||
154 | if isinstance(event, bb.command.CookerCommandCompleted): | 158 | if isinstance(event, bb.command.CookerCommandCompleted): |
diff --git a/bitbake/lib/bb/ui/uievent.py b/bitbake/lib/bb/ui/uievent.py index f1e4d791ee..b404805d81 100644 --- a/bitbake/lib/bb/ui/uievent.py +++ b/bitbake/lib/bb/ui/uievent.py | |||
@@ -37,8 +37,8 @@ class BBUIEventQueue: | |||
37 | self.BBServer = BBServer | 37 | self.BBServer = BBServer |
38 | 38 | ||
39 | self.t = threading.Thread() | 39 | self.t = threading.Thread() |
40 | self.t.setDaemon(True) | 40 | self.t.setDaemon(True) |
41 | self.t.run = self.startCallbackHandler | 41 | self.t.run = self.startCallbackHandler |
42 | self.t.start() | 42 | self.t.start() |
43 | 43 | ||
44 | def getEvent(self): | 44 | def getEvent(self): |
@@ -70,7 +70,7 @@ class BBUIEventQueue: | |||
70 | def startCallbackHandler(self): | 70 | def startCallbackHandler(self): |
71 | 71 | ||
72 | server = UIXMLRPCServer() | 72 | server = UIXMLRPCServer() |
73 | self.host, self.port = server.socket.getsockname() | 73 | self.host, self.port = server.socket.getsockname() |
74 | 74 | ||
75 | server.register_function( self.system_quit, "event.quit" ) | 75 | server.register_function( self.system_quit, "event.quit" ) |
76 | server.register_function( self.queue_event, "event.send" ) | 76 | server.register_function( self.queue_event, "event.send" ) |
@@ -83,7 +83,7 @@ class BBUIEventQueue: | |||
83 | server.handle_request() | 83 | server.handle_request() |
84 | server.server_close() | 84 | server.server_close() |
85 | 85 | ||
86 | def system_quit( self ): | 86 | def system_quit( self ): |
87 | """ | 87 | """ |
88 | Shut down the callback thread | 88 | Shut down the callback thread |
89 | """ | 89 | """ |
@@ -95,11 +95,11 @@ class BBUIEventQueue: | |||
95 | 95 | ||
96 | class UIXMLRPCServer (SimpleXMLRPCServer): | 96 | class UIXMLRPCServer (SimpleXMLRPCServer): |
97 | 97 | ||
98 | def __init__( self, interface = ("localhost", 0) ): | 98 | def __init__( self, interface = ("localhost", 0) ): |
99 | self.quit = False | 99 | self.quit = False |
100 | SimpleXMLRPCServer.__init__( self, | 100 | SimpleXMLRPCServer.__init__( self, |
101 | interface, | 101 | interface, |
102 | requestHandler=SimpleXMLRPCRequestHandler, | 102 | requestHandler=SimpleXMLRPCRequestHandler, |
103 | logRequests=False, allow_none=True) | 103 | logRequests=False, allow_none=True) |
104 | 104 | ||
105 | def get_request(self): | 105 | def get_request(self): |
@@ -121,4 +121,4 @@ class UIXMLRPCServer (SimpleXMLRPCServer): | |||
121 | if request is None: | 121 | if request is None: |
122 | return | 122 | return |
123 | SimpleXMLRPCServer.process_request(self, request, client_address) | 123 | SimpleXMLRPCServer.process_request(self, request, client_address) |
124 | 124 | ||