Skip to content

Commit

Permalink
🐛 Fix for Progress Bar and Resource Leak (#135)
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidBakerEffendi authored Mar 23, 2021
1 parent 9a49c97 commit 34fe42d
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 50 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).

## [0.3.9] - 2021-03-23

### Fixed

- Progress bar causing call graph pass to freeze on large graphs. This has been removed.
- Resource clearing was accidentally commented out in 0.3.8 - this has been addressed.

## [0.3.8] - 2021-03-23

### Added
Expand Down
2 changes: 1 addition & 1 deletion VERSION.md
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.3.8
0.3.9
2 changes: 1 addition & 1 deletion plume/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ dependencies {
implementation "org.soot-oss:soot:$sootVersion"
implementation "org.lz4:lz4-java:$lz4Version"
implementation "org.cache2k:cache2k-api:$cache2kVersion"
runtimeOnly "org.cache2k:cache2k-core:$cache2kVersion"
implementation "org.cache2k:cache2k-core:$cache2kVersion"

// Sub-project integration
subProject project(":cpgconv")
Expand Down
97 changes: 49 additions & 48 deletions plume/src/main/kotlin/io/github/plume/oss/Extractor.kt
Original file line number Diff line number Diff line change
Expand Up @@ -288,64 +288,65 @@ class Extractor(val driver: IDriver) {
.coerceAtLeast(1)
.coerceAtMost(Runtime.getRuntime().availableProcessors())
val channel = Channel<DeltaGraph>()
logger.info("Spawning $nThreads thread(s).")
// Create jobs in chunks and submit these jobs to a thread pool
val threadPool = Executors.newFixedThreadPool(nThreads)
try {
logger.info("Building ${headsToBuild.size} method heads")
runBlocking {
// Producer: Build method bodies and channel them through as delta graphs
launch {
headsToBuild.chunked(chunkSize)
.map { chunk -> Runnable { buildMethodHeads(chunk, channel) } }
.forEach(threadPool::submit)
}
// Consumer: Receive delta graphs and write changes to the driver in serial
launch {
logger.info("Spawning $nThreads thread(s).")
// Create jobs in chunks and submit these jobs to a thread pool
val threadPool = Executors.newFixedThreadPool(nThreads)
try {
logger.info("Building ${headsToBuild.size} method heads")
runBlocking {
// Producer: Build method bodies and channel them through as delta graphs
launch {
headsToBuild.chunked(chunkSize)
.map { chunk -> Runnable { buildMethodHeads(chunk, channel) } }
.forEach(threadPool::submit)
}
// Consumer: Receive delta graphs and write changes to the driver in serial
runInsideProgressBar("Method Heads", headsToBuild.size.toLong()) { pb ->
repeat(headsToBuild.size) { launch { channel.receive().apply(driver) }; pb?.step() }
runBlocking {
repeat(headsToBuild.size) { channel.receive().apply(driver); pb?.step() }
}
}
logger.debug("All ${headsToBuild.size} method heads have been applied to the driver")
}.join() // Suspend until the channel is fully consumed.
}
logger.info("Building ${bodiesToBuild.size} method bodies")
runBlocking {
// Producer: Build method bodies and channel them through as delta graphs
launch {
bodiesToBuild.chunked(chunkSize)
.map { chunk -> Runnable { buildBaseCPGs(chunk, channel) } }
.forEach(threadPool::submit)
logger.info("All ${headsToBuild.size} method heads have been applied to the driver")

}
// Consumer: Receive delta graphs and write changes to the driver in serial
launch {
logger.info("Building ${bodiesToBuild.size} method bodies")
runBlocking {
// Producer: Build method bodies and channel them through as delta graphs
launch {
bodiesToBuild.chunked(chunkSize)
.map { chunk -> Runnable { buildBaseCPGs(chunk, channel) } }
.forEach(threadPool::submit)
}
// Consumer: Receive delta graphs and write changes to the driver in serial
runInsideProgressBar("Method Bodies", bodiesToBuild.size.toLong()) { pb ->
repeat(bodiesToBuild.size) { launch { channel.receive().apply(driver) }; pb?.step() }
runBlocking {
repeat(bodiesToBuild.size) { channel.receive().apply(driver); pb?.step() }
}
}
logger.debug("All ${bodiesToBuild.size} method bodies have been applied to the driver")
}.join() // Suspend until the channel is fully consumed.
}
} finally {
threadPool.shutdown()
}
// Connect call edges. This is not done in parallel but asynchronously
logger.info("Constructing call graph edges")
runBlocking {
if (ExtractorOptions.callGraphAlg != ExtractorOptions.CallGraphAlg.NONE) {
// Producer: Build method calls and channel them through as delta graphs
launch {
bodiesToBuild.chunked(chunkSize)
.forEach { chunk -> buildCallGraph(chunk, channel) }
logger.info("All ${bodiesToBuild.size} method bodies have been applied to the driver")
}
// Consumer: Receive delta graphs and write changes to the driver in serial
launch {
runInsideProgressBar("Method Calls", bodiesToBuild.size.toLong()) { pb ->
repeat(bodiesToBuild.size) { launch { channel.receive().apply(driver) }; pb?.step() }
} finally {
threadPool.shutdown()
}
// Connect call edges. This is not done in parallel but asynchronously
logger.info("Constructing call graph edges")
runBlocking {
if (ExtractorOptions.callGraphAlg != ExtractorOptions.CallGraphAlg.NONE) {
// Producer: Build method calls and channel them through as delta graphs
launch {
bodiesToBuild.chunked(chunkSize).forEach { chunk -> buildCallGraph(chunk, channel) }
}
logger.debug("All ${bodiesToBuild.size} method calls have been applied to the driver")
}.join() // Suspend until the channel is fully consumed.
// Consumer: Receive delta graphs and write changes to the driver in serial
runBlocking {
repeat(bodiesToBuild.size) { channel.receive().apply(driver) }
}
logger.info("All ${bodiesToBuild.size} method calls have been applied to the driver")
}
}
} finally {
channel.close()
}
channel.close()
}

private fun runInsideProgressBar(pbName: String, barMax: Long, f: (pb: ProgressBar?) -> Unit) {
Expand Down

0 comments on commit 34fe42d

Please sign in to comment.