void UdpRcve( i8 *addr, u8 *frame, i32 length, void *parm ) { static udp_hdr_t UdpRcveudpHdr; static ip_hdr_t UdpRcveipHdr; link_t *link; udp_descr_t *descr = (udp_descr_t *) parm; bool success = FALSE; if(Addr2HostPort(addr, &UdpRcveipHdr.src, &UdpRcveudpHdr.src)) { UdpRcveipHdr.dst=descr->locAddr; UdpRcveudpHdr.dst=descr->locPort; link=LinkAlloc(0, frame, (u16)length, (u16)length, 0, 0); if(link!=0) { if(descr->Rcve(descr, link, &UdpRcveudpHdr, &UdpRcveipHdr)) { /* RcveUdp in agent.c */ success = TRUE; } LinkFree(link); } } if(success) udpStat.inDatagrams++; else udpStat.inErrors++; }
/* void* allocmem(AllocPool *pool, int32 size); void* allocmem(AllocPool *pool, int32 size) { return pool->Alloc(size); } void* reallocmem(AllocPool *pool, void* ptr, int32 size); void* reallocmem(AllocPool *pool, void* ptr, int32 size) { return pool->Realloc(ptr, size); } void freemem(AllocPool *pool, void* ptr); void freemem(AllocPool *pool, void* ptr) { pool->Free(ptr); } */ void AllocPool::InitAlloc() { if (mAreaInitSize == 0) return; /* alloc initial area */ NewArea(mAreaInitSize); /* get chunk */ AllocAreaPtr area = mAreas; AllocChunkPtr chunk = &area->mChunk; LinkFree(chunk); check_pool(); }
void AllocPool::FreeAllInternal() { check_pool(); InitBins(); AllocAreaPtr area = mAreas; if (area) { AllocAreaPtr firstArea = area; do { AllocAreaPtr nextarea = area->mNext; size_t size = area->mSize; AllocChunkPtr chunk = &area->mChunk; chunk->SetSizeFree(size); chunk->SetNeighborsInUse(size); LinkFree(chunk); area = nextarea; } while (area != firstArea); } check_pool(); }
void AllocPool::Free(void *inPtr) { #ifdef DISABLE_MEMORY_POOLS free(inPtr); return; #endif check_pool(); if (inPtr == 0) return; /* free(0) has no effect */ AllocChunkPtr chunk = MemToChunk(inPtr); check_inuse_chunk(chunk); garbage_fill(chunk); size_t size = chunk->Size(); if (!chunk->PrevInUse()) /* consolidate backward */ { size_t prevSize = chunk->PrevSize(); chunk = chunk->ChunkAtOffset(0L-prevSize); size += prevSize; UnlinkFree(chunk); } AllocChunkPtr next = chunk->ChunkAtOffset(size); if (!next->InUse()) /* consolidate forward */ { size += next->Size(); UnlinkFree(next); } chunk->SetSizeFree(size); if (mAreaMoreSize && chunk->IsArea()) { // whole area is free FreeArea(chunk); } else { LinkFree(chunk); } check_pool(); }
void* AllocPool::Alloc(size_t inReqSize) { #ifdef DISABLE_MEMORY_POOLS return malloc(inReqSize); #endif // OK it has a lot of gotos, but these remove a whole lot of common code // that was obfuscating the original version of this function. // So here I am choosing the OnceAndOnlyOnce principle over the caveats on gotos. // The gotos only jump forward and only to the exit paths of the function // The old bin block scheme has been replaced by 4 x 32 bit words so that each bin has a bit // and the next bin is found using a count leading zeroes instruction. Much faster. // Also now each bin's flag can be kept accurate. This simplifies the searching code quite a bit. // Also fwiw, changed 'victim' in the original code to 'candidate'. 'victim' just bothered me. AllocChunkPtr candidate; /* inspected/selected chunk */ size_t candidate_size; /* its size */ AllocChunkPtr remainder; /* remainder from a split */ int32 remainder_size; /* its size */ AllocAreaPtr area; size_t areaSize; size_t size = RequestToSize(inReqSize); int index = BinIndex(size); assert(index < 128); AllocChunkPtr bin = mBins + index; check_pool(); /* Check for exact match in a bin */ if (index < kMaxSmallBin) { /* Faster version for small requests */ /* No traversal or size check necessary for small bins. */ candidate = bin->Prev(); /* Also scan the next one, since it would have a remainder < kMinAllocSize */ if (candidate == bin) candidate = (++bin)->Prev(); if (candidate != bin) { candidate_size = candidate->Size(); goto found_exact_fit; } index += 2; /* Set for bin scan below. We've already scanned 2 bins. */ } else { for (candidate = bin->Prev(); candidate != bin; candidate = candidate->Prev()) { candidate_size = candidate->Size(); remainder_size = (int)(candidate_size - size); if (remainder_size >= (int32)kMinAllocSize) { /* too big */ --index; /* adjust to rescan below after checking last remainder */ break; } else if (remainder_size >= 0) { /* exact fit */ goto found_exact_fit; } } ++index; } for(; (index = NextFullBin(index)) >= 0; ++index) { bin = mBins + index; /* Find and use first big enough chunk ... */ for (candidate = bin->Prev(); candidate != bin; candidate = candidate->Prev()) { candidate_size = candidate->Size(); remainder_size = (int)(candidate_size - size); if (remainder_size >= (int32)kMinAllocSize) { /* split */ UnlinkFree(candidate); goto found_bigger_fit; } else if (remainder_size >= 0) goto found_exact_fit; } } check_pool(); if (mAreaMoreSize == 0) { /* pool has a non-growable area */ if (mAreas != NULL /* fixed size area exhausted */ || size > mAreaInitSize) /* too big anyway */ goto found_nothing; areaSize = mAreaInitSize; goto split_new_area; } if (size > mAreaMoreSize) { areaSize = size; goto whole_new_area; } else { areaSize = mAreaMoreSize; goto split_new_area; } // exit paths: found_nothing: //ipostbuf("alloc failed. size: %d\n", inReqSize); throw std::runtime_error("alloc failed, increase server's memory allocation (e.g. via ServerOptions)"); whole_new_area: //ipostbuf("whole_new_area\n"); area = NewArea(areaSize); if (!area) return 0; candidate = &area->mChunk; candidate_size = candidate->Size(); goto return_chunk; split_new_area: //ipostbuf("split_new_area\n"); area = NewArea(areaSize); if (!area) return 0; candidate = &area->mChunk; candidate_size = candidate->Size(); remainder_size = (int)(areaSize - size); // FALL THROUGH found_bigger_fit: //ipostbuf("found_bigger_fit\n"); remainder = candidate->ChunkAtOffset(size); remainder->SetSizeFree(remainder_size); candidate_size -= remainder_size; LinkFree(remainder); goto return_chunk; found_exact_fit: check_pool(); UnlinkFree(candidate); // FALL THROUGH return_chunk: candidate->SetSizeInUse(candidate_size); check_malloced_chunk(candidate, candidate_size); check_pool(); garbage_fill(candidate); return candidate->ToPtr(); }