void *VDJITAllocator::Allocate(size_t len) { len = (len + 15) & ~(size_t)15; FreeChunks::iterator itMark(mNextChunk), itEnd(mFreeChunks.end()), it(itMark); if (it == itEnd) it = mFreeChunks.begin(); for(;;) { for(; it!=itEnd; ++it) { if (it->second >= len) { it->second -= len; void *p = (char *)it->first + it->second; if (!it->second) { if (mNextChunk == it) ++mNextChunk; mFreeChunks.erase(it); } return p; } } if (itEnd == itMark) break; it = mFreeChunks.begin(); itEnd = itMark; } size_t alloclen = (len + mAllocationGranularity - 1) & ~(mAllocationGranularity - 1); void *p = VirtualAlloc(NULL, alloclen, MEM_COMMIT, PAGE_EXECUTE_READWRITE); if (p) { try { Allocations::iterator itA(mAllocations.insert(Allocations::value_type(p, alloclen)).first); try { if (len < alloclen) mFreeChunks.insert(FreeChunks::value_type((char *)p + len, alloclen - len)); } catch(...) { mAllocations.erase(itA); throw; } } catch(...) { VirtualFree(p, 0, MEM_RELEASE); p = NULL; } } return p; }
void VDJITAllocator::Free(void *p, size_t len) { VDASSERT(p); VDASSERT(len < 0x10000); FreeChunks::iterator cur(mFreeChunks.lower_bound(p)); if (cur != mFreeChunks.end() && (char *)p + len == cur->first) { len += cur->second; if (mNextChunk == cur) ++mNextChunk; cur = mFreeChunks.erase(cur); } if (cur != mFreeChunks.begin()) { FreeChunks::iterator prev(cur); --prev; if ((char *)prev->first + prev->second == p) { p = prev->first; len += prev->second; if (mNextChunk == prev) ++mNextChunk; mFreeChunks.erase(prev); } } uintptr start = (size_t)p; uintptr end = start + len; if (!((start | end) & (mAllocationGranularity - 1))) { Allocations::iterator it(mAllocations.find(p)); if (it != mAllocations.end()) { VirtualFree((void *)start, 0, MEM_RELEASE); mAllocations.erase(it); return; } } mFreeChunks.insert(FreeChunks::value_type((void *)start, end-start)); }
void Scheduler::schedLoop() { try { while (true) { readyQ->wait_not_empty(); // LOG(debug) << "Got job in schedLoop"; auto start = bc::system_clock::now(); Allocations *a = nullptr; if (resPool->size() > 0) { readyQ->lock(); a = this->algVec[MODE_MANAGED](*this); readyQ->unlock(); } else { continue; } /* managed to get some kind of schedule. */ size_t numJobsScheduled = a->noJobs(); if (numJobsScheduled > 0) { elasticityManager.updateResourcePool(*this, *a); a->serviceAllocations(*this); auto end = bc::system_clock::now(); auto duration = bc::duration_cast<bc::microseconds>(end - start); // LOGF(debug, "Scheduling took: %1%") % duration.count(); totalSchedTime += duration; numSchedules++; } delete a; // LOGF(debug, "MMode scheduled %1% job(s)") % numJobsScheduled; totalJobsScheduled += numJobsScheduled; // LOG(debug) << "\t(" << readyQ->size() << " Job(s) left)"; } } catch (std::exception &e) { // LOG(error) << "Scheduling thread - " << e.what(); } }