コード例 #1
0
ファイル: xudp.c プロジェクト: JoeAltmaier/Odyssey
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++;
}
コード例 #2
0
/*
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();
}
コード例 #3
0
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();
}
コード例 #4
0
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();
}
コード例 #5
0
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();
}