Skip to content

Commit

Permalink
Change context pooling to use a queue instead of a stack
Browse files Browse the repository at this point in the history
  • Loading branch information
pchintalapudi committed Apr 18, 2022
1 parent c9294ea commit c9b9dee
Showing 1 changed file with 29 additions and 6 deletions.
35 changes: 29 additions & 6 deletions src/jitlayers.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
#include "julia_assert.h"
#include "debug-registry.h"

#include <stack>
#include <queue>

// As of LLVM 13, there are two runtime JIT linker implementations, the older
// RuntimeDyld (used via orc::RTDyldObjectLinkingLayer) and the newer JITLink
// (used via orc::ObjectLinkingLayer).
Expand Down Expand Up @@ -222,7 +225,15 @@ class JuliaOJIT {
typedef orc::IRCompileLayer CompileLayerT;
typedef orc::IRTransformLayer OptimizeLayerT;
typedef object::OwningBinary<object::ObjectFile> OwningObj;
template<typename ResourceT, size_t max = 0>
template
<typename ResourceT, size_t max = 0,
typename BackingT = std::stack<ResourceT,
std::conditional_t<max == 0,
SmallVector<ResourceT>,
SmallVector<ResourceT, max>
>
>
>
struct ResourcePool {
public:
ResourcePool(std::function<ResourceT()> creator) : creator(std::move(creator)), mutex(std::make_unique<WNMutex>()) {}
Expand Down Expand Up @@ -281,25 +292,37 @@ class JuliaOJIT {
ResourceT acquire() {
std::unique_lock<std::mutex> lock(mutex->mutex);
if (!pool.empty()) {
return pool.pop_back_val();
return pop(pool);
}
if (!max || created < max) {
created++;
return creator();
}
mutex->empty.wait(lock, [&](){ return !pool.empty(); });
assert(!pool.empty() && "Expected resource pool to have a value!");
return pool.pop_back_val();
return pop(pool);
}
void release(ResourceT &&resource) {
std::lock_guard<std::mutex> lock(mutex->mutex);
pool.push_back(std::move(resource));
pool.push(std::move(resource));
mutex->empty.notify_one();
}
private:
template<typename T, typename Container>
static ResourceT pop(std::queue<T, Container> &pool) {
ResourceT top = std::move(pool.front());
pool.pop();
return top;
}
template<typename PoolT>
static ResourceT pop(PoolT &pool) {
ResourceT top = std::move(pool.top());
pool.pop();
return top;
}
std::function<ResourceT()> creator;
size_t created = 0;
llvm::SmallVector<ResourceT, max == 0 ? 8 : max> pool;
BackingT pool;
struct WNMutex {
std::mutex mutex;
std::condition_variable empty;
Expand Down Expand Up @@ -393,7 +416,7 @@ class JuliaOJIT {

JITDebugInfoRegistry DebugRegistry;

ResourcePool<orc::ThreadSafeContext> ContextPool;
ResourcePool<orc::ThreadSafeContext, 0, std::queue<orc::ThreadSafeContext>> ContextPool;

#ifndef JL_USE_JITLINK
const std::shared_ptr<RTDyldMemoryManager> MemMgr;
Expand Down

0 comments on commit c9b9dee

Please sign in to comment.