GstBuffer *QGstXvImageBufferPool::takeBuffer( const QVideoSurfaceFormat &format, GstCaps *caps) { m_poolMutex.lock(); m_caps = caps; if (format != m_format) { doClear(); m_format = format; } if (m_pool.isEmpty()) { //qDebug() << "QGstXvImageBufferPool::takeBuffer: no buffer available, allocate the new one" << QThread::currentThreadId() << m_threadId; if (QThread::currentThreadId() == m_threadId) { doAlloc(); } else { QMetaObject::invokeMethod(this, "queuedAlloc", Qt::QueuedConnection); m_allocWaitCondition.wait(&m_poolMutex, 300); } } QGstXvImageBuffer *res = 0; if (!m_pool.isEmpty()) { res = m_pool.takeLast(); } m_poolMutex.unlock(); return GST_BUFFER(res); }
asmlinkage int sys_netmalloc(net_malloc_arg_t *arg) { switch(arg->action) { case A_ALLOC: doAlloc(arg); break; case A_FREE: doFree(arg); break; } return 0; }
void BB::allocate_to_preferred_candidates_if_possible(fint use_count[], fint def_count[]) { RegCandidateBList cands(nnodes); for (Node* n = first; n != last->next(); n = n->next()) { if (n->deleted) continue; n->markAllocated(use_count, def_count); if (n->isAssignNode()) pick_candidates_for_assignment_node(n, use_count, def_count, cands); } // now examine all candidates and allocate them to preferred register // if possible while (cands.nonEmpty()) { RegCandidate* c = cands.pop(); if (def_count[c->loc] == c->ndefs) { doAlloc(c->r, c->loc); } } }
void BB::allocateTempRegisters(BitVector** hardwired, PRegBList* tempRegs, BitVectorBList* lives) { if (!nnodes) return; // empty BB RegisterEqClassBList regClasses(nnodes + 1); regClasses.append(NULL); // first reg class has index 1 fint use_count[NumRegisters], def_count[NumRegisters]; for (fint i = 0; i < NumRegisters; i++) use_count[i] = def_count[i] = 0; allocate_to_preferred_candidates_if_possible(use_count, def_count); // allocate other temp regs (using the untouched temp regs of this BB) fint temp = 0; for (int i = 0; i < duInfo.info->length(); i++) { // collect temp regs PReg* r = duInfo.info->nth(i)->reg; if (r->loc == UnAllocated && !r->isUnused() && r->isLocalTo(this)) { assert(r->dus.first()->index == i, "should be the same"); for ( ; temp < NumTempRegs && use_count[TempRegs[temp]] + def_count[TempRegs[temp]] > 0; temp++) ; if (temp == NumTempRegs) break; // ran out of regs // ok, allocate TempRegs[temp] to the preg and equivalent pregs Location t = TempRegs[temp++]; PReg* frst = r->regClass ? regClasses.nth(r->regClass)->first : r; for (PReg* pr = frst; pr; pr = pr->regClassLink) { doAlloc(pr, t); pr->regClass = 0; } } r->regClass = 0; } if (temp == NumTempRegs) { // ran out of temp regs with the simple strategy - try using slow // allocation algorithm slowAllocateTempRegisters(hardwired, tempRegs, lives); } }
void QGstXvImageBufferPool::queuedAlloc() { QMutexLocker lock(&m_poolMutex); doAlloc(); m_allocWaitCondition.wakeOne(); }
// allocate PRegs that are used & defined solely within this BB void BB::slowAllocateTempRegisters(BitVector** hardwired, PRegBList* tempRegs, BitVectorBList* lives) { // clear temporary data structures tempRegs->clear(); lives->clear(); fint i; for (i = 0; i < NumTempRegs; i++) { hardwired[i]->setLength(nnodes); hardwired[i]->clear(); } for (i = 0; i < duInfo.info->length(); i++) { // collect temp regs and hardwired temp regs PReg* r = duInfo.info->nth(i)->reg; if (r->isLocalTo(this)) { assert(r->dus.first()->index == i, "should be the same"); if (r->isUnused()) { // unused register - ignore } else { DUInfo* info = duInfo.info->nth(r->dus.first()->index); tempRegs->append(r); BitVector* bv = new BitVector(nnodes); lives->append(bv); fint firstUse = 0, lastUse = nnodes - 1; duInfo.info->nth(i)->getLiveRange(firstUse, lastUse); bv->addFromTo(firstUse, lastUse); } } else if (isTempReg(r->loc)) { fint firstUse = 0, lastUse = nnodes - 1; if (!r->incorrectDU()) { duInfo.info->nth(i)->getLiveRange(firstUse, lastUse); } else { // can't really compute live range since the temp might be non-local // so assume it's live from first node til the end } hardwired[RegToTempNo[r->loc]]->addFromTo(firstUse, lastUse); } } // now, tempRegs holds all temp regs, and lives contains each register's // live range (one bit per node, 1 = reg is live); hardwired contains // the ranges where temp regs are already taken (e.g. for NLR, calls, etc) // cycle through the temp registers to (hopefully) allow more optimizations // later (e.g. scheduling) fint lastTemp = 0; # define nextTemp(n) (n == NumTempRegs - 1) ? 0 : n + 1 for (i = 0; i < tempRegs->length(); i++) { // try to allocate tempRegs[i] to a temp register PReg* r = tempRegs->nth(i); if (r->loc != UnAllocated) { assert(r->regClass == 0, "should have been cleared"); continue; } BitVector* liveRange = lives->nth(i); for (fint tempNo = lastTemp, ntries = 0; ntries < NumTempRegs; tempNo = nextTemp(tempNo), ntries++) { if (liveRange->isDisjointFrom(hardwired[tempNo])) { Location temp = TempRegs[tempNo]; doAlloc(r, temp); hardwired[tempNo]->unionWith(liveRange); lastTemp = nextTemp(tempNo); break; } } if ( r->loc == UnAllocated && (PrintSICTempRegisterAllocation || WizardMode && TARGET_ARCH != I386_ARCH /* happens normally in I386; few regs */ )) { lprintf("*could NOT find temp assignment for local %s in BB%ld\n", r->name(), (void*)id()); } else if (r->loc == UnAllocated) { if (PrintSICTempRegisterAllocation) lprintf("out of temp regs"); } r->regClass = 0; } }
// Allocates the specified amount of bytes in the buffer virtual void* alloc(size_t bytes) { alignNextAlloc(); if (!canAlloc(bytes)) return NULL; return doAlloc(bytes); }