void releaseSections(Uint32 secCount, SegmentedSectionPtr ptr[3]){ Uint32 tSec0 = ptr[0].i; Uint32 tSz0 = ptr[0].sz; Uint32 tSec1 = ptr[1].i; Uint32 tSz1 = ptr[1].sz; Uint32 tSec2 = ptr[2].i; Uint32 tSz2 = ptr[2].sz; switch(secCount){ case 3: g_sectionSegmentPool.releaseList(relSz(tSz2), tSec2, ptr[2].p->m_lastSegment); case 2: g_sectionSegmentPool.releaseList(relSz(tSz1), tSec1, ptr[1].p->m_lastSegment); case 1: g_sectionSegmentPool.releaseList(relSz(tSz0), tSec0, ptr[0].p->m_lastSegment); case 0: return; } char msg[40]; sprintf(msg, "secCount=%d", secCount); ErrorReporter::handleAssert(msg, __FILE__, __LINE__); }
void getSections(Uint32 secCount, SegmentedSectionPtr ptr[3]){ Uint32 tSec0 = ptr[0].i; Uint32 tSec1 = ptr[1].i; Uint32 tSec2 = ptr[2].i; SectionSegment * p; switch(secCount){ case 3: p = g_sectionSegmentPool.getPtr(tSec2); ptr[2].p = p; ptr[2].sz = p->m_sz; case 2: p = g_sectionSegmentPool.getPtr(tSec1); ptr[1].p = p; ptr[1].sz = p->m_sz; case 1: p = g_sectionSegmentPool.getPtr(tSec0); ptr[0].p = p; ptr[0].sz = p->m_sz; case 0: return; } char msg[40]; sprintf(msg, "secCount=%d", secCount); ErrorReporter::handleAssert(msg, __FILE__, __LINE__); }
int main(int arg, char** argv) { /* Test SectionReader * ------------------- * To run this code : * cd storage/ndb/src/kernel/vm * make testSectionReader * ./testSectionReader * * Will print "OK" in success case and return 0 */ g_sectionSegmentPool.setSize(1024); printf("g_sectionSegmentPool size is %u\n", g_sectionSegmentPool.getSize()); const Uint32 Iterations= 2000; const Uint32 Sections= 5; Uint32 sizes[ Sections ]; Uint32 iVals[ Sections ]; for (Uint32 t=0; t < Iterations; t++) { for (Uint32 i=0; i<Sections; i++) { Uint32 available= g_sectionSegmentPool.getNoOfFree(); sizes[i] = available ? myRandom48(SectionSegment::DataLength * available) : 0; //if (0 == (sizes[i] % 60)) // printf("Iteration %u, section %u, allocating %u words\n", // t, i, sizes[i]); if (t % 100 == 0) if (i==0) printf("\nIteration %u", t); if (sizes[i] > 0) { iVals[i]= createSection(&g_sectionSegmentPool, sizes[i]); VERIFY(testSR(iVals[i], &g_sectionSegmentPool, sizes[i]) == 0); } else iVals[i]= RNIL; } for (Uint32 i=0; i < Sections; i++) { if (sizes[i] > 0) freeSection(&g_sectionSegmentPool, iVals[i]); } } printf("\nOK\n"); return 0; }
void test(Uint32 sz, Uint32 loops, Uint32 iter){ ndbout_c("SimplePropertiesSection sz=%d loops=%d iter=%d", sz, loops, iter); while(loops-- > 0){ Uint32 size = sz*((10 + (rand() % (10 * sz)) + sz - 1)/sz); Buffer buf(size); SectionSegmentPool thePool; thePool.setSize(size); for(Uint32 i = 0; i<iter; i++){ Uint32 c = 0 + (rand() % (2)); const Uint32 alloc = 1 + (rand() % (size - 1)); SegmentedSectionPtr dst; if(0) ndbout_c("size: %d loops: %d iter: %d c=%d alloc=%d", size, loops, i, c, alloc); switch(c){ case 0:{ for(Uint32 i = 0; i<alloc; i++) buf.buffer[i] = i; //rand(); buf.m_len = alloc; SimplePropertiesSectionWriter w(thePool); for(Uint32 i = 0; i<alloc; i++){ w.putWord(buf.buffer[i]); } w.getPtr(dst); break; } case 1:{ for(Uint32 i = 0; i<alloc; i++) buf.buffer[i] = i; //rand(); buf.m_len = alloc; SimplePropertiesSectionWriter w(thePool); Uint32 i = 0; while(i < alloc){ Uint32 sz = rand() % (alloc - i + 1); w.putWords(&buf.buffer[i], sz); i += sz; } w.getPtr(dst); break; } case 2:{ break; } } SimplePropertiesSectionReader r(dst, thePool); compare(r, buf); release(thePool, dst); require(thePool.getSize() == thePool.getNoOfFree()); } } }
/** * verifySection * Assertion method to check that a segmented section is constructed * 'properly' where 'properly' is loosly defined. */ bool verifySection(Uint32 firstIVal, SectionSegmentPool& thePool) { if (firstIVal == RNIL) return true; /* Get first section ptr (With assertions in getPtr) */ SectionSegment* first= thePool.getPtr(firstIVal); assert(first != NULL); Uint32 totalSize= first->m_sz; Uint32 lastSegIVal= first->m_lastSegment; /* Hmm, need to be careful of length == 0 * Nature abhors a segmented section with length 0 */ //assert(totalSize != 0); assert(lastSegIVal != RNIL); /* Should never be == RNIL */ /* We ignore m_ownerRef */ if (totalSize <= SectionSegment::DataLength) { /* 1 segment */ assert(first->m_lastSegment == firstIVal); // m_nextSegment not always set to RNIL on last segment //assert(first->m_nextSegment == RNIL); } else { /* > 1 segment */ assert(first->m_nextSegment != RNIL); assert(first->m_lastSegment != firstIVal); Uint32 currIVal= firstIVal; SectionSegment* curr= first; /* Traverse segments to where we think the end should be */ while (totalSize > SectionSegment::DataLength) { currIVal= curr->m_nextSegment; curr= thePool.getPtr(currIVal); totalSize-= SectionSegment::DataLength; /* Ignore m_ownerRef, m_sz, m_lastSegment of intermediate * Segments */ } /* Once we are here, we are on the last Segment of this Section * Check that last segment is as stated in the first segment */ assert(currIVal == lastSegIVal); // m_nextSegment not always set properly on last segment //assert(curr->m_nextSegment == RNIL); /* Ignore m_ownerRef, m_sz, m_lastSegment of last segment */ } return true; }
void getSection(SegmentedSectionPtr & ptr, Uint32 i){ ptr.i = i; SectionSegment * p = g_sectionSegmentPool.getPtr(i); ptr.p = p; ptr.sz = p->m_sz; }
void release(SectionSegmentPool & thePool, SegmentedSectionPtr & ptr){ const Uint32 sz = relSz(ptr.sz); thePool.releaseList(sz, ptr.i, ptr.p->m_lastSegment); }
void linkSegments(Uint32 head, Uint32 tail){ Ptr<SectionSegment> headPtr; g_sectionSegmentPool.getPtr(headPtr, head); Ptr<SectionSegment> tailPtr; g_sectionSegmentPool.getPtr(tailPtr, tail); Ptr<SectionSegment> oldTailPtr; g_sectionSegmentPool.getPtr(oldTailPtr, headPtr.p->m_lastSegment); headPtr.p->m_lastSegment = tailPtr.p->m_lastSegment; headPtr.p->m_sz += tailPtr.p->m_sz; oldTailPtr.p->m_nextSegment = tailPtr.i; }
void print(SegmentedSectionPtr ptr, FILE* out){ ptr.p = g_sectionSegmentPool.getPtr(ptr.i); Uint32 len = ptr.p->m_sz; fprintf(out, "ptr.i = %d(%p) ptr.sz = %d(%d)\n", ptr.i, ptr.p, len, ptr.sz); while(len > SectionSegment::DataLength){ print(ptr.p, SectionSegment::DataLength, out); len -= SectionSegment::DataLength; fprintf(out, "ptr.i = %d\n", ptr.p->m_nextSegment); ptr.p = g_sectionSegmentPool.getPtr(ptr.p->m_nextSegment); } print(ptr.p, len, out); fprintf(out, "\n"); }
void append(DataBuffer<sz>& dst, SegmentedSectionPtr ptr, SectionSegmentPool& pool) { Uint32 len = ptr.sz; while(len > SectionSegment::DataLength) { dst.append(ptr.p->theData, SectionSegment::DataLength); ptr.p = pool.getPtr(ptr.p->m_nextSegment); len -= SectionSegment::DataLength; } dst.append(ptr.p->theData, len); }
bool import(Ptr<SectionSegment> & first, const Uint32 * src, Uint32 len){ /** * Dummy data used when setting prev.m_nextSegment for first segment of a * section */ Uint32 dummyPrev[4]; first.p = 0; if(g_sectionSegmentPool.seize(first)){ ; } else { return false; } first.p->m_sz = len; first.p->m_ownerRef = 0; Ptr<SectionSegment> prevPtr = { (SectionSegment *)&dummyPrev[0], 0 }; Ptr<SectionSegment> currPtr = first; while(len > SectionSegment::DataLength){ prevPtr.p->m_nextSegment = currPtr.i; memcpy(&currPtr.p->theData[0], src, 4 * SectionSegment::DataLength); src += SectionSegment::DataLength; len -= SectionSegment::DataLength; prevPtr = currPtr; if(g_sectionSegmentPool.seize(currPtr)){ ; } else { first.p->m_lastSegment = prevPtr.i; return false; } } first.p->m_lastSegment = currPtr.i; currPtr.p->m_nextSegment = RNIL; memcpy(&currPtr.p->theData[0], src, 4 * len); return true; }
void SignalLoggerManager::printSegmentedSection(FILE * output, const SignalHeader & sh, const SegmentedSectionPtr ptr[3], unsigned i) { fprintf(output, "SECTION %u type=segmented", i); if (i >= 3) { fprintf(output, " *** invalid ***\n"); return; } const Uint32 len = ptr[i].sz; SectionSegment * ssp = ptr[i].p; Uint32 pos = 0; fprintf(output, " size=%u\n", (unsigned)len); while (pos < len) { if (pos > 0 && pos % SectionSegment::DataLength == 0) { ssp = g_sectionSegmentPool.getPtr(ssp->m_nextSegment); } printDataWord(output, pos, ssp->theData[pos % SectionSegment::DataLength]); } if (len > 0) putc('\n', output); }
void execute(void * callbackObj, SignalHeader * const header, Uint8 prio, Uint32 * const theData, LinearSectionPtr ptr[3]){ const Uint32 secCount = header->m_noOfSections; const Uint32 length = header->theLength; #ifdef TRACE_DISTRIBUTED ndbout_c("recv: %s(%d) from (%s, %d)", getSignalName(header->theVerId_signalNumber), header->theVerId_signalNumber, getBlockName(refToBlock(header->theSendersBlockRef)), refToNode(header->theSendersBlockRef)); #endif bool ok = true; Ptr<SectionSegment> secPtr[3]; switch(secCount){ case 3: ok &= import(secPtr[2], ptr[2].p, ptr[2].sz); case 2: ok &= import(secPtr[1], ptr[1].p, ptr[1].sz); case 1: ok &= import(secPtr[0], ptr[0].p, ptr[0].sz); } /** * Check that we haven't received a too long signal */ ok &= (length + secCount <= 25); Uint32 secPtrI[3]; if(ok){ /** * Normal path */ secPtrI[0] = secPtr[0].i; secPtrI[1] = secPtr[1].i; secPtrI[2] = secPtr[2].i; globalScheduler.execute(header, prio, theData, secPtrI); return; } /** * Out of memory */ for(Uint32 i = 0; i<secCount; i++){ if(secPtr[i].p != 0){ g_sectionSegmentPool.releaseList(relSz(ptr[i].sz), secPtr[i].i, secPtr[i].p->m_lastSegment); } } Uint32 gsn = header->theVerId_signalNumber; Uint32 len = header->theLength; Uint32 newLen= (len > 22 ? 22 : len); SignalDroppedRep * rep = (SignalDroppedRep*)theData; memmove(rep->originalData, theData, (4 * newLen)); rep->originalGsn = gsn; rep->originalLength = len; rep->originalSectionCount = secCount; header->theVerId_signalNumber = GSN_SIGNAL_DROPPED_REP; header->theLength = newLen + 3; header->m_noOfSections = 0; globalScheduler.execute(header, prio, theData, secPtrI); }
void release(SegmentedSectionPtr & ptr){ g_sectionSegmentPool.releaseList(relSz(ptr.sz), ptr.i, ptr.p->m_lastSegment); }