mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-12-12 06:02:56 +00:00
Merge remote-tracking branch
'origin/GP-3195-dragonmacher-parallel-decomp-api-tweak' (Closes #5091)
This commit is contained in:
commit
8bab4179bc
@ -18,8 +18,7 @@ package ghidra.app.decompiler.parallel;
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import generic.concurrent.QCallback;
|
||||
import generic.concurrent.QResult;
|
||||
import generic.concurrent.*;
|
||||
import ghidra.app.util.DecompilerConcurrentQ;
|
||||
import ghidra.program.model.address.AddressSetView;
|
||||
import ghidra.program.model.listing.*;
|
||||
@ -31,8 +30,8 @@ public class ParallelDecompiler {
|
||||
|
||||
/**
|
||||
* Decompile the given functions using multiple decompilers
|
||||
*
|
||||
* @param callback the callback to be called for each that is processed
|
||||
*
|
||||
* @param callback the callback to be called for each item that is processed
|
||||
* @param program the program
|
||||
* @param addresses the addresses restricting which functions to decompile
|
||||
* @param monitor the task monitor
|
||||
@ -53,8 +52,8 @@ public class ParallelDecompiler {
|
||||
|
||||
/**
|
||||
* Decompile the given functions using multiple decompilers
|
||||
*
|
||||
* @param callback the callback to be called for each that is processed
|
||||
*
|
||||
* @param callback the callback to be called for each item that is processed
|
||||
* @param functions the functions to decompile
|
||||
* @param monitor the task monitor
|
||||
* @return the list of client results
|
||||
@ -62,41 +61,40 @@ public class ParallelDecompiler {
|
||||
* @throws Exception if any other exception occurs
|
||||
*/
|
||||
public static <R> List<R> decompileFunctions(QCallback<Function, R> callback,
|
||||
Collection<Function> functions,
|
||||
TaskMonitor monitor)
|
||||
Collection<Function> functions, TaskMonitor monitor)
|
||||
throws InterruptedException, Exception {
|
||||
|
||||
List<R> results =
|
||||
doDecompileFunctions(callback, functions.iterator(), functions.size(),
|
||||
monitor);
|
||||
doDecompileFunctions(callback, functions.iterator(), functions.size(), monitor);
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decompile the given functions using multiple decompilers.
|
||||
*
|
||||
*
|
||||
* <p>Results will be passed to the given consumer as they are produced. Calling this
|
||||
* method allows you to handle results as they are discovered.
|
||||
*
|
||||
* method allows you to handle results as they are discovered.
|
||||
*
|
||||
* <p><strong>This method will wait for all processing before returning.</strong>
|
||||
*
|
||||
*
|
||||
* @param callback the callback to be called for each that is processed
|
||||
* @param program the program
|
||||
* @param program the program
|
||||
* @param functions the functions to decompile
|
||||
* @param resultsConsumer the consumer to which results will be passed
|
||||
* @param monitor the task monitor
|
||||
* @throws InterruptedException if interrupted
|
||||
* @throws Exception if any other exception occurs
|
||||
*/
|
||||
public static <R> void decompileFunctions(QCallback<Function, R> callback,
|
||||
Program program,
|
||||
Iterator<Function> functions, Consumer<R> resultsConsumer,
|
||||
TaskMonitor monitor)
|
||||
public static <R> void decompileFunctions(QCallback<Function, R> callback, Program program,
|
||||
Iterator<Function> functions, Consumer<R> resultsConsumer, TaskMonitor monitor)
|
||||
throws InterruptedException, Exception {
|
||||
|
||||
int max = program.getFunctionManager().getFunctionCount();
|
||||
boolean collectResults = false; // the client will process results as they arrive
|
||||
GThreadPool threadPool = GThreadPool.getSharedThreadPool(THREAD_POOL_NAME);
|
||||
DecompilerConcurrentQ<Function, R> queue =
|
||||
new DecompilerConcurrentQ<>(callback, THREAD_POOL_NAME, monitor);
|
||||
new DecompilerConcurrentQ<>(callback, threadPool, collectResults, monitor);
|
||||
|
||||
monitor.initialize(max);
|
||||
queue.process(functions, resultsConsumer);
|
||||
queue.waitUntilDone();
|
||||
@ -130,14 +128,14 @@ public class ParallelDecompiler {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an object that can be used to perform decompilation of a limited number of
|
||||
* Creates an object that can be used to perform decompilation of a limited number of
|
||||
* functions at a time, as opposed to working over an entire range of functions at once.
|
||||
* {@link #decompileFunctions(QCallback, Program, AddressSetView, TaskMonitor)} will create
|
||||
* and tear down concurrent data structures on each use, making repeated calls less efficient.
|
||||
* You would use this method when you wish to perform periodic work as results are returned
|
||||
* You would use this method when you wish to perform periodic work as results are returned
|
||||
* <b>and when using the callback mechanism is not sufficient</b> such as when ordering of
|
||||
* results is required.
|
||||
*
|
||||
* results is required.
|
||||
*
|
||||
* @param callback the callback required to perform work.
|
||||
* @param monitor the monitor used to report progress and to cancel
|
||||
* @return the parallel decompiler used for decompiling.
|
||||
|
@ -28,14 +28,14 @@ import utility.function.Dummy;
|
||||
/**
|
||||
* A class to perform some of the boilerplate setup of the {@link ConcurrentQ} that is shared
|
||||
* amongst clients that perform decompilation in parallel.
|
||||
*
|
||||
* <p>This class can be used in a blocking or non-blocking fashion.
|
||||
*
|
||||
*
|
||||
* <p>This class can be used in a blocking or non-blocking fashion.
|
||||
*
|
||||
* <ul>
|
||||
* <li>For blocking usage, call
|
||||
* one of the <u>{@code add}</u> methods to put items in the queue and then call
|
||||
* {@link #waitForResults()}.</li>
|
||||
* <li>For non-blocking usage, simply call
|
||||
* one of the <u>{@code add}</u> methods to put items in the queue and then call
|
||||
* {@link #waitForResults()}.</li>
|
||||
* <li>For non-blocking usage, simply call
|
||||
* {@link #process(Iterator, Consumer)}, passing the consumer of the results.</li>
|
||||
* </ol>
|
||||
* <p>
|
||||
@ -50,22 +50,23 @@ public class DecompilerConcurrentQ<I, R> {
|
||||
private Consumer<R> resultConsumer = Dummy.consumer();
|
||||
|
||||
public DecompilerConcurrentQ(QCallback<I, R> callback, TaskMonitor monitor) {
|
||||
this(callback, AutoAnalysisManager.getSharedAnalsysThreadPool(), monitor);
|
||||
this(callback, AutoAnalysisManager.getSharedAnalsysThreadPool(), true, monitor);
|
||||
}
|
||||
|
||||
public DecompilerConcurrentQ(QCallback<I, R> callback, String threadPoolName,
|
||||
TaskMonitor monitor) {
|
||||
this(callback, GThreadPool.getSharedThreadPool(threadPoolName), monitor);
|
||||
this(callback, GThreadPool.getSharedThreadPool(threadPoolName), true, monitor);
|
||||
}
|
||||
|
||||
private DecompilerConcurrentQ(QCallback<I, R> callback, GThreadPool pool, TaskMonitor monitor) {
|
||||
public DecompilerConcurrentQ(QCallback<I, R> callback, GThreadPool pool, boolean collectResults,
|
||||
TaskMonitor monitor) {
|
||||
// @formatter:off
|
||||
queue = new ConcurrentQBuilder<I, R>()
|
||||
.setCollectResults(true)
|
||||
.setCollectResults(collectResults)
|
||||
.setThreadPool(pool)
|
||||
.setMonitor(monitor)
|
||||
.setListener(new InternalResultListener())
|
||||
.build(callback);
|
||||
.build(callback);
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
@ -84,7 +85,7 @@ public class DecompilerConcurrentQ<I, R> {
|
||||
/**
|
||||
* Adds all items to the queue for processing. The results will be passed to the given consumer
|
||||
* as they are produced.
|
||||
*
|
||||
*
|
||||
* @param functions the functions to process
|
||||
* @param consumer the results consumer
|
||||
*/
|
||||
@ -96,7 +97,7 @@ public class DecompilerConcurrentQ<I, R> {
|
||||
/**
|
||||
* Waits for all results to be delivered. The client is responsible for processing the
|
||||
* results and handling any exceptions that may have occurred.
|
||||
*
|
||||
*
|
||||
* @return all results
|
||||
* @throws InterruptedException if interrupted while waiting
|
||||
*/
|
||||
@ -110,10 +111,10 @@ public class DecompilerConcurrentQ<I, R> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits for all work to finish. Any exception encountered will trigger all processing to
|
||||
* stop. If you wish for the work to continue despite exceptions, then use
|
||||
* Waits for all work to finish. Any exception encountered will trigger all processing to
|
||||
* stop. If you wish for the work to continue despite exceptions, then use
|
||||
* {@link #waitForResults()}.
|
||||
*
|
||||
*
|
||||
* @throws InterruptedException if interrupted while waiting
|
||||
* @throws Exception any exception that is encountered while processing items.
|
||||
*/
|
||||
@ -131,9 +132,9 @@ public class DecompilerConcurrentQ<I, R> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls dispose on the queue being processed. Further, the call will block for up to
|
||||
* <tt>timeoutSeconds</tt> while waiting for the queue to finish processing.
|
||||
*
|
||||
* Calls dispose on the queue being processed. Further, the call will block for up to
|
||||
* <tt>timeoutSeconds</tt> while waiting for the queue to finish processing.
|
||||
*
|
||||
* @param timeoutSeconds the number of seconds to wait for the disposed queue to finish
|
||||
* processing
|
||||
*/
|
||||
@ -164,7 +165,7 @@ public class DecompilerConcurrentQ<I, R> {
|
||||
}
|
||||
}
|
||||
catch (Throwable t) {
|
||||
// This code is an asynchronous callback. Handle the exception the same way as
|
||||
// This code is an asynchronous callback. Handle the exception the same way as
|
||||
// the waitXyz() method do, which is to shutdown the queue.
|
||||
Msg.error(this, "Unexpected exception getting Decompiler result", t);
|
||||
queue.dispose();
|
||||
|
Loading…
Reference in New Issue
Block a user