void Trix:: execBUILDINDXREQ(Signal* signal) { jamEntry(); DBUG_ENTER("Trix:: execBUILDINDXREQ"); BuildIndxReq * buildIndxReq = (BuildIndxReq *)signal->getDataPtr(); // Seize a subscription record SubscriptionRecPtr subRecPtr; SubscriptionRecord* subRec; if (!c_theSubscriptions.seizeId(subRecPtr, buildIndxReq->getBuildId())) { // Failed to allocate subscription record BuildIndxRef * buildIndxRef = (BuildIndxRef *)signal->getDataPtrSend(); buildIndxRef->setErrorCode(BuildIndxRef::AllocationFailure); releaseSections(signal); sendSignal(buildIndxReq->getUserRef(), GSN_BUILDINDXREF, signal, BuildIndxRef::SignalLength, JBB); DBUG_VOID_RETURN; } subRec = subRecPtr.p; subRec->errorCode = BuildIndxRef::NoError; subRec->userReference = buildIndxReq->getUserRef(); subRec->connectionPtr = buildIndxReq->getConnectionPtr(); subRec->subscriptionId = buildIndxReq->getBuildId(); subRec->subscriptionKey = buildIndxReq->getBuildKey(); subRec->indexType = buildIndxReq->getIndexType(); subRec->sourceTableId = buildIndxReq->getTableId(); subRec->targetTableId = buildIndxReq->getIndexId(); subRec->parallelism = buildIndxReq->getParallelism(); subRec->expectedConf = 0; subRec->subscriptionCreated = false; subRec->pendingSubSyncContinueConf = false; subRec->prepareId = RNIL; // Get column order segments Uint32 noOfSections = signal->getNoOfSections(); if(noOfSections > 0) { SegmentedSectionPtr ptr; signal->getSection(ptr, BuildIndxReq::INDEX_COLUMNS); append(subRec->attributeOrder, ptr, getSectionSegmentPool()); subRec->noOfIndexColumns = ptr.sz; } if(noOfSections > 1) { SegmentedSectionPtr ptr; signal->getSection(ptr, BuildIndxReq::KEY_COLUMNS); append(subRec->attributeOrder, ptr, getSectionSegmentPool()); subRec->noOfKeyColumns = ptr.sz; } #if 0 // Debugging printf("Trix:: execBUILDINDXREQ: Attribute order:\n"); subRec->attributeOrder.print(stdout); #endif releaseSections(signal); prepareInsertTransactions(signal, subRecPtr); DBUG_VOID_RETURN; }
/** * execROUTE_ORD * Allows other blocks to route signals as if they * came from TRPMAN * Useful in ndbmtd for synchronising signals w.r.t * external signals received from other nodes which * arrive from the same thread that runs TRPMAN */ void Trpman::execROUTE_ORD(Signal* signal) { jamEntry(); if (!assembleFragments(signal)) { jam(); return; } SectionHandle handle(this, signal); RouteOrd* ord = (RouteOrd*)signal->getDataPtr(); Uint32 dstRef = ord->dstRef; Uint32 srcRef = ord->srcRef; Uint32 gsn = ord->gsn; /* ord->cnt ignored */ Uint32 nodeId = refToNode(dstRef); if (likely((nodeId == 0) || getNodeInfo(nodeId).m_connected)) { jam(); Uint32 secCount = handle.m_cnt; ndbrequire(secCount >= 1 && secCount <= 3); jamLine(secCount); /** * Put section 0 in signal->theData */ Uint32 sigLen = handle.m_ptr[0].sz; ndbrequire(sigLen <= 25); copy(signal->theData, handle.m_ptr[0]); SegmentedSectionPtr save = handle.m_ptr[0]; for (Uint32 i = 0; i < secCount - 1; i++) handle.m_ptr[i] = handle.m_ptr[i+1]; handle.m_cnt--; sendSignal(dstRef, gsn, signal, sigLen, JBB, &handle); handle.m_cnt = 1; handle.m_ptr[0] = save; releaseSections(handle); return ; } releaseSections(handle); warningEvent("Unable to route GSN: %d from %x to %x", gsn, srcRef, dstRef); }
void Ndbfs::execFSOPENREQ(Signal* signal) { jamEntry(); const FsOpenReq * const fsOpenReq = (FsOpenReq *)&signal->theData[0]; const BlockReference userRef = fsOpenReq->userReference; AsyncFile* file = getIdleFile(); ndbrequire(file != NULL); Filename::NameSpec spec(theFileSystemPath, theBackupFilePath); Uint32 userPointer = fsOpenReq->userPointer; if(fsOpenReq->fileFlags & FsOpenReq::OM_INIT) { Ptr<GlobalPage> page_ptr; if(m_global_page_pool.seize(page_ptr) == false) { FsRef * const fsRef = (FsRef *)&signal->theData[0]; fsRef->userPointer = userPointer; fsRef->setErrorCode(fsRef->errorCode, FsRef::fsErrOutOfMemory); fsRef->osErrorCode = ~0; // Indicate local error sendSignal(userRef, GSN_FSOPENREF, signal, 3, JBB); return; } file->m_page_ptr = page_ptr; } else { ndbassert(file->m_page_ptr.isNull()); file->m_page_ptr.setNull(); } if(signal->getNoOfSections() == 0){ jam(); file->theFileName.set(spec, userRef, fsOpenReq->fileNumber); } else { jam(); SegmentedSectionPtr ptr; signal->getSection(ptr, FsOpenReq::FILENAME); file->theFileName.set(spec, ptr, g_sectionSegmentPool); releaseSections(signal); } file->reportTo(&theFromThreads); if (getenv("NDB_TRACE_OPEN")) ndbout_c("open(%s)", file->theFileName.c_str()); Request* request = theRequestPool->get(); request->action = Request::open; request->error = 0; request->set(userRef, userPointer, newId() ); request->file = file; request->theTrace = signal->getTrace(); request->par.open.flags = fsOpenReq->fileFlags; request->par.open.page_size = fsOpenReq->page_size; request->par.open.file_size = fsOpenReq->file_size_hi; request->par.open.file_size <<= 32; request->par.open.file_size |= fsOpenReq->file_size_lo; request->par.open.auto_sync_size = fsOpenReq->auto_sync_size; ndbrequire(forward(file, request)); }
//------------------------------------------------------------------------ // sendPacked is executed at the end of the loop. // To ensure that we don't send any messages before executing all local // packed signals we do another turn in the loop (unless we have already // executed too many signals in the loop). //------------------------------------------------------------------------ void FastScheduler::doJob() { Uint32 loopCount = 0; Uint32 TminLoops = getBOccupancy() + EXTRA_SIGNALS_PER_DO_JOB; Uint32 TloopMax = (Uint32)globalData.loopMax; if (TminLoops < TloopMax) { TloopMax = TminLoops; }//if if (TloopMax < MIN_NUMBER_OF_SIG_PER_DO_JOB) { TloopMax = MIN_NUMBER_OF_SIG_PER_DO_JOB; }//if register Signal* signal = getVMSignals(); register Uint32 tHighPrio= globalData.highestAvailablePrio; do{ while ((tHighPrio < LEVEL_IDLE) && (loopCount < TloopMax)) { // signal->garbage_register(); // To ensure we find bugs quickly register Uint32 gsnbnr = theJobBuffers[tHighPrio].retrieve(signal); register BlockNumber reg_bnr = gsnbnr & 0xFFF; register GlobalSignalNumber reg_gsn = gsnbnr >> 16; globalData.incrementWatchDogCounter(1); if (reg_bnr > 0) { Uint32 tJobCounter = globalData.JobCounter; Uint32 tJobLap = globalData.JobLap; SimulatedBlock* b = globalData.getBlock(reg_bnr); theJobPriority[tJobCounter] = (Uint8)tHighPrio; globalData.JobCounter = (tJobCounter + 1) & 4095; globalData.JobLap = tJobLap + 1; #ifdef VM_TRACE_TIME Uint32 us1, us2; Uint64 ms1, ms2; NdbTick_CurrentMicrosecond(&ms1, &us1); b->m_currentGsn = reg_gsn; #endif getSections(signal->header.m_noOfSections, signal->m_sectionPtr); #ifdef VM_TRACE { if (globalData.testOn) { signal->header.theVerId_signalNumber = reg_gsn; signal->header.theReceiversBlockNumber = reg_bnr; globalSignalLoggers.executeSignal(signal->header, tHighPrio, &signal->theData[0], globalData.ownId, signal->m_sectionPtr, signal->header.m_noOfSections); }//if } #endif b->executeFunction(reg_gsn, signal); releaseSections(signal->header.m_noOfSections, signal->m_sectionPtr); signal->header.m_noOfSections = 0; #ifdef VM_TRACE_TIME NdbTick_CurrentMicrosecond(&ms2, &us2); Uint64 diff = ms2; diff -= ms1; diff *= 1000000; diff += us2; diff -= us1; b->addTime(reg_gsn, diff); #endif tHighPrio = globalData.highestAvailablePrio; } else { tHighPrio++; globalData.highestAvailablePrio = tHighPrio; }//if loopCount++; }//while sendPacked(); tHighPrio = globalData.highestAvailablePrio; if(getBOccupancy() > MAX_OCCUPANCY) { if(loopCount != TloopMax) abort(); assert( loopCount == TloopMax ); TloopMax += 512; } } while ((getBOccupancy() > MAX_OCCUPANCY) || ((loopCount < TloopMax) && (tHighPrio < LEVEL_IDLE))); theDoJobCallCounter ++; theDoJobTotalCounter += loopCount; if (theDoJobCallCounter == 8192) { reportDoJobStatistics(theDoJobTotalCounter >> 13); theDoJobCallCounter = 0; theDoJobTotalCounter = 0; }//if