coroutines on windows...
This commit is contained in:
@@ -287,9 +287,9 @@ public:
|
||||
return insertedElement;
|
||||
}
|
||||
// front + popFront
|
||||
value_type&& retrieve()
|
||||
value_type retrieve()
|
||||
{
|
||||
auto&& temp = std::move(root->data);
|
||||
value_type temp = std::move(root->data);
|
||||
popFront();
|
||||
return std::move(temp);
|
||||
}
|
||||
|
||||
@@ -133,57 +133,58 @@ void Allocation::markFree(SubAllocation *allocation)
|
||||
PSubAllocation allocHandle;
|
||||
PSubAllocation freeRangeToDelete;
|
||||
|
||||
std::unique_lock lck(lock);
|
||||
//Join lower bound
|
||||
for (auto freeRange : freeRanges)
|
||||
{
|
||||
PSubAllocation freeAlloc = freeRange.value;
|
||||
if (freeAlloc->allocatedOffset <= lowerBound
|
||||
&& freeAlloc->allocatedOffset + freeAlloc->allocatedSize >= upperBound)
|
||||
std::unique_lock lck(lock);
|
||||
//Join lower bound
|
||||
for (auto freeRange : freeRanges)
|
||||
{
|
||||
// allocation is already in a free region
|
||||
return;
|
||||
PSubAllocation freeAlloc = freeRange.value;
|
||||
if (freeAlloc->allocatedOffset <= lowerBound
|
||||
&& freeAlloc->allocatedOffset + freeAlloc->allocatedSize >= upperBound)
|
||||
{
|
||||
// allocation is already in a free region
|
||||
return;
|
||||
}
|
||||
if (freeAlloc->allocatedOffset + freeAlloc->allocatedSize == lowerBound)
|
||||
{
|
||||
//extend freeAlloc by the allocatedSize
|
||||
freeAlloc->allocatedSize += allocation->allocatedSize;
|
||||
allocHandle = freeAlloc;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (freeAlloc->allocatedOffset + freeAlloc->allocatedSize == lowerBound)
|
||||
//Join upper bound
|
||||
auto foundAlloc = freeRanges.find(upperBound);
|
||||
if (foundAlloc != freeRanges.end())
|
||||
{
|
||||
//extend freeAlloc by the allocatedSize
|
||||
freeAlloc->allocatedSize += allocation->allocatedSize;
|
||||
allocHandle = freeAlloc;
|
||||
break;
|
||||
freeRangeToDelete = foundAlloc->value;
|
||||
// There is a free allocation ending where the new free one ends
|
||||
if (allocHandle != nullptr)
|
||||
{
|
||||
// extend allocHandle by another foundAlloc->allocatedSize bytes
|
||||
allocHandle->allocatedSize += foundAlloc->value->allocatedSize;
|
||||
freeRanges.erase(foundAlloc->key);
|
||||
}
|
||||
else
|
||||
{
|
||||
// set foundAlloc back by size amount
|
||||
allocHandle = foundAlloc->value;
|
||||
allocHandle->allocatedOffset -= allocation->allocatedSize;
|
||||
allocHandle->alignedOffset -= allocation->allocatedSize;
|
||||
// place back at correct offset
|
||||
freeRanges[allocHandle->allocatedOffset] = allocHandle;
|
||||
// remove from offset map since key changes
|
||||
freeRanges.erase(foundAlloc->key);
|
||||
}
|
||||
}
|
||||
|
||||
if (allocHandle == nullptr)
|
||||
{
|
||||
allocHandle = new SubAllocation(this, allocation->alignedOffset, allocation->size, allocation->alignedOffset, allocation->allocatedSize);
|
||||
freeRanges[allocation->allocatedOffset] = allocHandle;
|
||||
}
|
||||
activeAllocations.erase(allocation->allocatedOffset);
|
||||
}
|
||||
//Join upper bound
|
||||
auto foundAlloc = freeRanges.find(upperBound);
|
||||
if (foundAlloc != freeRanges.end())
|
||||
{
|
||||
freeRangeToDelete = foundAlloc->value;
|
||||
// There is a free allocation ending where the new free one ends
|
||||
if (allocHandle != nullptr)
|
||||
{
|
||||
// extend allocHandle by another foundAlloc->allocatedSize bytes
|
||||
allocHandle->allocatedSize += foundAlloc->value->allocatedSize;
|
||||
freeRanges.erase(foundAlloc->key);
|
||||
}
|
||||
else
|
||||
{
|
||||
// set foundAlloc back by size amount
|
||||
allocHandle = foundAlloc->value;
|
||||
allocHandle->allocatedOffset -= allocation->allocatedSize;
|
||||
allocHandle->alignedOffset -= allocation->allocatedSize;
|
||||
// place back at correct offset
|
||||
freeRanges[allocHandle->allocatedOffset] = allocHandle;
|
||||
// remove from offset map since key changes
|
||||
freeRanges.erase(foundAlloc->key);
|
||||
}
|
||||
}
|
||||
|
||||
if (allocHandle == nullptr)
|
||||
{
|
||||
allocHandle = new SubAllocation(this, allocation->alignedOffset, allocation->size, allocation->alignedOffset, allocation->allocatedSize);
|
||||
freeRanges[allocation->allocatedOffset] = allocHandle;
|
||||
}
|
||||
activeAllocations.erase(allocation->allocatedOffset);
|
||||
lock.unlock();
|
||||
bytesUsed -= allocation->allocatedSize;
|
||||
// TODO: delete allocation when bytesUsed == 0
|
||||
}
|
||||
|
||||
+41
-22
@@ -47,25 +47,26 @@ ThreadPool::~ThreadPool()
|
||||
void ThreadPool::addJob(Job&& job)
|
||||
{
|
||||
std::unique_lock lock(jobQueueLock);
|
||||
std::cout << "Adding job " << job.id << std::endl;
|
||||
jobQueue.add(std::move(job));
|
||||
jobQueueCV.notify_one();
|
||||
}
|
||||
void ThreadPool::addJob(MainJob&& job)
|
||||
{
|
||||
std::unique_lock lock(mainJobLock);
|
||||
//std::cout << "Adding main job " << std::addressof(job.handle) << std::endl;
|
||||
std::cout << "Adding main job " << job.id << std::endl;
|
||||
mainJobs.add(std::move(job));
|
||||
mainJobCV.notify_one();
|
||||
}
|
||||
void ThreadPool::enqueueWaiting(Event* event, Job&& job)
|
||||
{
|
||||
//std::cout << job << " waiting for event " << event->name << std::endl;
|
||||
std::cout << job.id << " waiting for event " << event->name << std::endl;
|
||||
std::unique_lock lock(waitingLock);
|
||||
waitingJobs[*event].add(std::move(job));
|
||||
}
|
||||
void ThreadPool::enqueueWaiting(Event* event, MainJob&& job)
|
||||
{
|
||||
//std::cout << std::addressof(job.handle) << " main waiting for event " << event->name << std::endl;
|
||||
std::cout << job.id << " main waiting for event " << event->name << std::endl;
|
||||
std::unique_lock lock(waitingMainLock);
|
||||
waitingMainJobs[*event].add(std::move(job));
|
||||
}
|
||||
@@ -76,8 +77,9 @@ void ThreadPool::notify(Event* event)
|
||||
std::unique_lock lock2(waitingLock);
|
||||
while(!waitingJobs[*event].empty())
|
||||
{
|
||||
//std::cout << "Waking up job " << job << std::endl;
|
||||
jobQueue.add(std::move(waitingJobs[*event].retrieve()));
|
||||
std::cout << "Waking up job " << waitingJobs[*event].front().id << std::endl;
|
||||
Job job = std::move(waitingJobs[*event].retrieve());
|
||||
jobQueue.add(std::move(job));
|
||||
jobQueueCV.notify_one();
|
||||
}
|
||||
}
|
||||
@@ -86,37 +88,54 @@ void ThreadPool::notify(Event* event)
|
||||
std::unique_lock lock2(waitingMainLock);
|
||||
while(!waitingMainJobs[*event].empty())
|
||||
{
|
||||
std::cout << "Waking up main job " << waitingMainJobs[*event].front().id << std::endl;
|
||||
mainJobs.add(std::move(waitingMainJobs[*event].retrieve()));
|
||||
mainJobCV.notify_one();
|
||||
}
|
||||
}
|
||||
}
|
||||
void ThreadPool::tryMainJob()
|
||||
{
|
||||
MainJob job;
|
||||
{
|
||||
std::unique_lock lock(mainJobLock);
|
||||
if(!mainJobs.empty())
|
||||
{
|
||||
job = std::move(mainJobs.retrieve());
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
job.resume();
|
||||
}
|
||||
void ThreadPool::threadLoop(const bool mainThread)
|
||||
{
|
||||
while(running.load())
|
||||
{
|
||||
if(mainThread)
|
||||
{
|
||||
std::unique_lock lock(mainJobLock);
|
||||
if(!mainJobs.empty())
|
||||
tryMainJob();
|
||||
}
|
||||
Job job;
|
||||
{
|
||||
std::unique_lock lock(jobQueueLock);
|
||||
if(jobQueue.empty())
|
||||
{
|
||||
MainJob&& job = mainJobs.retrieve();
|
||||
lock.unlock();
|
||||
job.resume();
|
||||
jobQueueCV.wait(lock);
|
||||
}
|
||||
if(!jobQueue.empty())
|
||||
{
|
||||
job = std::move(jobQueue.retrieve());
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
std::unique_lock lock(jobQueueLock);
|
||||
if(jobQueue.empty())
|
||||
{
|
||||
jobQueueCV.wait(lock);
|
||||
}
|
||||
if(!jobQueue.empty())
|
||||
{
|
||||
Job&& job = jobQueue.retrieve();
|
||||
lock.unlock();
|
||||
//std::cout << "Starting job " << job << std::endl;
|
||||
job.resume();
|
||||
}
|
||||
std::cout << "Starting job " << job.id << std::endl;
|
||||
job.resume();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ struct JobPromiseBase
|
||||
exit(1);
|
||||
};
|
||||
};
|
||||
static std::atomic_uint64_t globalCounter;
|
||||
template<bool MainJob>
|
||||
struct JobBase
|
||||
{
|
||||
@@ -32,10 +33,13 @@ public:
|
||||
using promise_type = JobPromiseBase<MainJob>;
|
||||
|
||||
explicit JobBase()
|
||||
: id(-1)
|
||||
{}
|
||||
explicit JobBase(std::coroutine_handle<promise_type> handle)
|
||||
: handle(handle)
|
||||
, id(globalCounter++)
|
||||
{
|
||||
std::cout << "Creating job " << id << std::endl;
|
||||
/*if constexpr(MainJob)
|
||||
{
|
||||
std::cout << "Creating mainjob " << handle.address() << std::endl;
|
||||
@@ -48,13 +52,16 @@ public:
|
||||
JobBase(const JobBase & rhs) = delete;
|
||||
JobBase(JobBase&& rhs)
|
||||
: handle(std::move(rhs.handle))
|
||||
, id(std::move(rhs.id))
|
||||
{
|
||||
rhs.id = -1;
|
||||
rhs.handle = nullptr;
|
||||
}
|
||||
~JobBase()
|
||||
{
|
||||
if(handle)
|
||||
{
|
||||
std::cout << "Destroying job " << id << std::endl;
|
||||
handle.destroy();
|
||||
}
|
||||
}
|
||||
@@ -64,6 +71,8 @@ public:
|
||||
if(this != &rhs)
|
||||
{
|
||||
handle = std::move(rhs.handle);
|
||||
id = std::move(rhs.id);
|
||||
rhs.id = -1;
|
||||
rhs.handle = nullptr;
|
||||
}
|
||||
return *this;
|
||||
@@ -73,6 +82,7 @@ public:
|
||||
handle.resume();
|
||||
}
|
||||
std::coroutine_handle<promise_type> handle;
|
||||
uint64 id;
|
||||
private:
|
||||
};
|
||||
|
||||
@@ -138,6 +148,7 @@ private:
|
||||
Map<Event, List<MainJob>> waitingMainJobs;
|
||||
std::mutex waitingMainLock;
|
||||
|
||||
void tryMainJob();
|
||||
void threadLoop(const bool isMainThread);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user