diff options
-rw-r--r-- | bitbake/lib/bb/cooker.py | 30 |
1 files changed, 18 insertions, 12 deletions
diff --git a/bitbake/lib/bb/cooker.py b/bitbake/lib/bb/cooker.py index 2bb80e330d..dc131939ed 100644 --- a/bitbake/lib/bb/cooker.py +++ b/bitbake/lib/bb/cooker.py | |||
@@ -26,6 +26,7 @@ import json | |||
26 | import pickle | 26 | import pickle |
27 | import codecs | 27 | import codecs |
28 | import hashserv | 28 | import hashserv |
29 | import ctypes | ||
29 | 30 | ||
30 | logger = logging.getLogger("BitBake") | 31 | logger = logging.getLogger("BitBake") |
31 | collectlog = logging.getLogger("BitBake.Collection") | 32 | collectlog = logging.getLogger("BitBake.Collection") |
@@ -1998,8 +1999,9 @@ class ParsingFailure(Exception): | |||
1998 | Exception.__init__(self, realexception, recipe) | 1999 | Exception.__init__(self, realexception, recipe) |
1999 | 2000 | ||
2000 | class Parser(multiprocessing.Process): | 2001 | class Parser(multiprocessing.Process): |
2001 | def __init__(self, jobs, results, quit, profile): | 2002 | def __init__(self, jobs, next_job_id, results, quit, profile): |
2002 | self.jobs = jobs | 2003 | self.jobs = jobs |
2004 | self.next_job_id = next_job_id | ||
2003 | self.results = results | 2005 | self.results = results |
2004 | self.quit = quit | 2006 | self.quit = quit |
2005 | multiprocessing.Process.__init__(self) | 2007 | multiprocessing.Process.__init__(self) |
@@ -2065,10 +2067,14 @@ class Parser(multiprocessing.Process): | |||
2065 | break | 2067 | break |
2066 | 2068 | ||
2067 | job = None | 2069 | job = None |
2068 | try: | 2070 | if havejobs: |
2069 | job = self.jobs.pop() | 2071 | with self.next_job_id.get_lock(): |
2070 | except IndexError: | 2072 | if self.next_job_id.value < len(self.jobs): |
2071 | havejobs = False | 2073 | job = self.jobs[self.next_job_id.value] |
2074 | self.next_job_id.value += 1 | ||
2075 | else: | ||
2076 | havejobs = False | ||
2077 | |||
2072 | if job: | 2078 | if job: |
2073 | result = self.parse(*job) | 2079 | result = self.parse(*job) |
2074 | # Clear the siggen cache after parsing to control memory usage, its huge | 2080 | # Clear the siggen cache after parsing to control memory usage, its huge |
@@ -2134,13 +2140,13 @@ class CookerParser(object): | |||
2134 | 2140 | ||
2135 | self.bb_caches = bb.cache.MulticonfigCache(self.cfgbuilder, self.cfghash, cooker.caches_array) | 2141 | self.bb_caches = bb.cache.MulticonfigCache(self.cfgbuilder, self.cfghash, cooker.caches_array) |
2136 | self.fromcache = set() | 2142 | self.fromcache = set() |
2137 | self.willparse = set() | 2143 | self.willparse = [] |
2138 | for mc in self.cooker.multiconfigs: | 2144 | for mc in self.cooker.multiconfigs: |
2139 | for filename in self.mcfilelist[mc]: | 2145 | for filename in self.mcfilelist[mc]: |
2140 | appends = self.cooker.collections[mc].get_file_appends(filename) | 2146 | appends = self.cooker.collections[mc].get_file_appends(filename) |
2141 | layername = self.cooker.collections[mc].calc_bbfile_priority(filename)[2] | 2147 | layername = self.cooker.collections[mc].calc_bbfile_priority(filename)[2] |
2142 | if not self.bb_caches[mc].cacheValid(filename, appends): | 2148 | if not self.bb_caches[mc].cacheValid(filename, appends): |
2143 | self.willparse.add((mc, self.bb_caches[mc], filename, appends, layername)) | 2149 | self.willparse.append((mc, self.bb_caches[mc], filename, appends, layername)) |
2144 | else: | 2150 | else: |
2145 | self.fromcache.add((mc, self.bb_caches[mc], filename, appends, layername)) | 2151 | self.fromcache.add((mc, self.bb_caches[mc], filename, appends, layername)) |
2146 | 2152 | ||
@@ -2159,18 +2165,18 @@ class CookerParser(object): | |||
2159 | def start(self): | 2165 | def start(self): |
2160 | self.results = self.load_cached() | 2166 | self.results = self.load_cached() |
2161 | self.processes = [] | 2167 | self.processes = [] |
2168 | |||
2162 | if self.toparse: | 2169 | if self.toparse: |
2163 | bb.event.fire(bb.event.ParseStarted(self.toparse), self.cfgdata) | 2170 | bb.event.fire(bb.event.ParseStarted(self.toparse), self.cfgdata) |
2164 | 2171 | ||
2172 | next_job_id = multiprocessing.Value(ctypes.c_int, 0) | ||
2165 | self.parser_quit = multiprocessing.Event() | 2173 | self.parser_quit = multiprocessing.Event() |
2166 | self.result_queue = multiprocessing.Queue() | 2174 | self.result_queue = multiprocessing.Queue() |
2167 | 2175 | ||
2168 | def chunkify(lst,n): | 2176 | # Have to pass in willparse at fork time so all parsing processes have the unpickleable data |
2169 | return [lst[i::n] for i in range(n)] | 2177 | # then access it by index from the parse queue. |
2170 | self.jobs = chunkify(list(self.willparse), self.num_processes) | ||
2171 | |||
2172 | for i in range(0, self.num_processes): | 2178 | for i in range(0, self.num_processes): |
2173 | parser = Parser(self.jobs[i], self.result_queue, self.parser_quit, self.cooker.configuration.profile) | 2179 | parser = Parser(self.willparse, next_job_id, self.result_queue, self.parser_quit, self.cooker.configuration.profile) |
2174 | parser.start() | 2180 | parser.start() |
2175 | self.process_names.append(parser.name) | 2181 | self.process_names.append(parser.name) |
2176 | self.processes.append(parser) | 2182 | self.processes.append(parser) |