Пример #1
0
/*
 * FreeQue search
 *	Search the free area whose size is equal to 'blksz',
 *	or larger than
 *      'blksz' but closest.
 *	If it does not exist, return '&imacb->freeque'.
 */
EXPORT QUEUE* knl_searchFreeArea( IMACB *imacb, W blksz )
{
	QUEUE	*q = &imacb->freeque;

	/* For area whose memory pool size is less than 1/4,
	   search from smaller size.
	   Otherwise, search from larger size. */
	if ( blksz > imacb->memsz / 4 ) {
		/* Search from larger size. */
		W fsz = 0;
		while ( (q = q->prev) != &imacb->freeque ) {
			fsz = FreeSize(q);
			if ( fsz <= blksz ) {
				return ( fsz < blksz )? q->next: q;
			}
		}
		return ( fsz >= blksz )? q->next: q;
	} else {
		/* Search from smaller size. */
		while ( (q = q->next) != &imacb->freeque ) {
			if ( FreeSize(q) >= blksz ) {
				break;
			}
		}
		return q;
	}
}
Пример #2
0
/*
 * FreeQue search
 *	Search the free area whose size is equal to 'blksz',
 *	or larger than
 *      'blksz' but closest.
 *	If it does not exist, return '&mplcb->freeque'.
 */
LOCAL QUEUE* searchFreeArea( MPLCB *mplcb, INT blksz )
{
	QUEUE	*q = &mplcb->freeque;

	/* For area whose memory pool size is less than 1/4,
	   search from smaller size.
	   Otherwise, search from larger size. */
	if ( blksz > mplcb->mplsz / 4 ) {
		/* Search from larger size. */
		INT fsz = 0;
		while ( (q = q->prev) != &mplcb->freeque ) {
			fsz = FreeSize(q);
			if ( fsz <= blksz ) {
				return ( fsz < blksz )? q->next: q;
			}
		}
		return ( fsz >= blksz )? q->next: q;
	} else {
		/* Search from smaller size. */
		while ( (q = q->next) != &mplcb->freeque ) {
			if ( FreeSize(q) >= blksz ) {
				break;
			}
		}
		return q;
	}
}
Пример #3
0
/*
 * Free queue search
 *	Searches for a free space with the same size as 'size' or
 *	the next largest.
 *      If none is found, returns &freeque.
 */
LIST *searchFreeArea( RAW_U32 size, MACB *macb )
{
	LIST	*q = &macb->freeque;

	/*
	 * Areas up to 1/4 of page size are searched starting
	 * from the smallest;
         * others are searched starting from the largest.
	 */
	if ( size > macb->pagesz / 4 ) {
		/* Searches in order of increasing size */
		RAW_U32 fsz = 0;
		while ( (q = q->previous) != &macb->freeque ) {
			fsz = (RAW_U32)FreeSize(q);
			if ( fsz <= size ) {
				return ( fsz < size )? q->next: q;
			}
		}
		return ( fsz >= size )? q->next: q;
	} else {
		/* Searches in order of decreasing size */
		while ( (q = q->next) != &macb->freeque ) {
			if ( (RAW_U32)FreeSize(q) >= size ) {
				break;
			}
		}
		return q;
	}
}
Пример #4
0
/*
 * FreeQue search
 *	Search free area whose size is equal to 'blksz', or closest and
 *	larger than 'blksz'.
 *	If it can not be found, return '&imacb->freeque'.
 */
LOCAL QUEUE* searchFreeArea( size_t blksz, IMACB *imacb )
{
	QUEUE	*q = &imacb->freeque;

	/* For area that is less than 1/4 of the page size, search from
	   smaller size. Otherwise, search from larger size. */
	if ( blksz > (pagesz / 4) ) {
		/* Search from larger size */
		size_t fsz = 0;
		while ( (q = q->prev) != &imacb->freeque ) {
			fsz = FreeSize(q);
			if ( fsz <= blksz ) {
				return ( fsz < blksz )? q->next: q;
			}
		}
		return ( fsz >= blksz )? q->next: q;
	} else {
		/* Search from smaller size */
		while ( (q = q->next) != &imacb->freeque ) {
			if ( FreeSize(q) >= blksz ) {
				break;
			}
		}
		return q;
	}
}
Пример #5
0
/*
 * Registration of free area on FreeQue
 *	FreeQue is composed of 2 types: Queue that links the
 *	different size of areas by size and queue that links the
 *	same size of areas.
 *
 *	freeque
 *	|
 *	|   +-----------------------+	    +-----------------------+
 *	|   | AreaQue		    |	    | AreaQue		    |
 *	|   +-----------------------+	    +-----------------------+
 *	*---> FreeQue Size order    |	    | EmptyQue		    |
 *	|   | FreeQue Same size   --------->| FreeQue Same size   ----->
 *	|   |			    |	    |			    |
 *	|   |			    |	    |			    |
 *	|   +-----------------------+	    +-----------------------+
 *	|   | AreaQue		    |	    | AreaQue		    |
 *	v   +-----------------------+	    +-----------------------+
 */
EXPORT void knl_appendFreeArea( IMACB *imacb, QUEUE *aq )
{
	QUEUE	*fq;
	W	size = AreaSize(aq);

	/* Registration position search */
	/*  Search the free area whose size is equal to 'blksz',
	 *  or larger than 'blksz' but closest.
	 *  If it does not exist, return '&imacb->freeque'.
	 */
	fq = knl_searchFreeArea(imacb, size);

	/* Register */
	clrAreaFlag(aq, AREA_USE);
	if ( fq != &imacb->freeque && FreeSize(fq) == size ) {
		/* FreeQue Same size */
		(aq + 2)->next = (fq + 1)->next;
		(fq + 1)->next = aq + 2;
		(aq + 2)->prev = fq + 1;
		if( (aq + 2)->next != NULL ) {
			(aq + 2)->next->prev = aq + 2;
		}
		(aq + 1)->next = NULL;
	} else {
		/* FreeQue Size order */
		QueInsert(aq + 1, fq);
		(aq + 2)->next = NULL;
		(aq + 2)->prev = (QUEUE*)size;
	}
}
Пример #6
0
/*
 * Refer variable size memory pool state
 */
SYSCALL ER _td_ref_mpl( ID mplid, TD_RMPL *pk_rmpl )
{
	MPLCB	*mplcb;
	QUEUE	*fq, *q;
	INT	frsz, blksz;
	ER	ercd = E_OK;

	CHECK_MPLID(mplid);

	mplcb = get_mplcb(mplid);

	BEGIN_DISABLE_INTERRUPT;
	if ( mplcb->mplid == 0 ) {
		ercd = E_NOEXS;
	} else {
		pk_rmpl->exinf = mplcb->exinf;
		pk_rmpl->wtsk  = wait_tskid(&mplcb->wait_queue);
		frsz = 0;
		for ( fq = mplcb->freeque.next; fq != &mplcb->freeque; fq = fq->next ) {
			blksz = FreeSize(fq);
			frsz += blksz;
			for ( q = (fq+1)->next; q != (fq+1); q = q->next ) {
				frsz += blksz;
			}
		}
		pk_rmpl->frsz  = frsz;
		pk_rmpl->maxsz = MaxFreeSize(mplcb);
	}
	END_DISABLE_INTERRUPT;

	return ercd;
}
Пример #7
0
/*
 * Maximum free area size
 */
Inline INT MaxFreeSize( MPLCB *mplcb )
{
	if ( isQueEmpty(&mplcb->freeque) ) {
		return 0;
	}
	return FreeSize(mplcb->freeque.prev);
}
Пример #8
0
/*
 * Get memory 
 */
EXPORT void* knl_Imalloc( size_t size )
{
	QUEUE	*q, *aq, *aq2;
	UINT	imask;

	/* If it is smaller than the minimum fragment size,
	   allocate the minimum size to it. */
	if ( size < MIN_FRAGMENT ) {
		size = MIN_FRAGMENT;
	} else {
		size = ROUND(size);
	}

	DI(imask);  /* Exclusive control by interrupt disable */

	/* Search FreeQue */
	q = knl_searchFreeArea(knl_imacb, size);
	if ( q == &(knl_imacb->freeque) ) {
		q = NULL; /* Insufficient memory */
		goto err_ret;
	}

	/* There is free area: Split from FreeQue once */
	knl_removeFreeQue(q);

	aq = q - 1;

	/* If there are fragments smaller than the minimum fragment size,
	   allocate them also */
	if ( FreeSize(q) - size >= MIN_FRAGMENT + sizeof(QUEUE) ) {

		/* Divide area into 2 */
		aq2 = (QUEUE*)((VB*)(aq + 1) + size);
		knl_insertAreaQue(aq, aq2);

		/* Register remaining area to FreeQue */
		knl_appendFreeArea(knl_imacb, aq2);
	}
	setAreaFlag(aq, AREA_USE);

err_ret:
	EI(imask);

	return (VP)q;
}
Пример #9
0
/*
 * Registration in free space free queue
 *	Free queue comprises a two-tier structure: a queue linking
 *	areas of differing size in order of size, and a queue
 *	linking areas that are the same size.
 *
 *     macb->freeque
 *      |
 *	|   +-----------------------+		+-----------------------+
 *	|   | AreaQue		    |		| AreaQue		|
 *	|   +-----------------------+		+-----------------------+
 *	+----> FreeQue size order   |	 +--------> FreeQue same size ----->
 *	|   |  FreeQue same size --------+      |   EmptyQue		|
 *	|   |			    |		|			|
 *	|   |			    |		|			|
 *	|   +-----------------------+		+-----------------------+
 *	|   | AreaQue		    |		| AreaQue		|
 *	|   +-----------------------+		+-----------------------+
 */
void appendFreeArea( LIST *aq, MACB *macb )
{
	LIST	*fq;
	RAW_U32	size = (RAW_U32)AreaSize(aq);

	/* Search registration position */
	/*  Searches for a free space with the same size as 'size' or
	 *  the next largest.
	 *  If none is found, returns &freeque.
	 */
	fq = searchFreeArea(size, macb);

	/* Registration */
	clrAreaFlag(aq, AREA_USE);
	if ( fq != &macb->freeque && (RAW_U32)FreeSize(fq) == size ) {
		list_insert(fq + 1, aq + 1);
	} else {
		list_insert(fq, aq + 1);
	}
	list_init(aq + 2);
}
Пример #10
0
/*
 * Registration of free area on FreeQue
 *	FreeQue is composed of 2 types: Queue that links the
 *	different size of areas by size and queue that links the
 *	same size of areas.
 *
 *	freeque
 *	|
 *	|   +-----------------------+	    +-----------------------+
 *	|   | AreaQue		    |	    | AreaQue		    |
 *	|   +-----------------------+	    +-----------------------+
 *	*---> FreeQue Size order    |  *----> FreeQue Same size   ----->
 *	|   | FreeQue Same size   -----*    | EmptyQue		    |
 *	|   |			    |	    |			    |
 *	|   |			    |	    |			    |
 *	|   +-----------------------+	    +-----------------------+
 *	|   | AreaQue		    |	    | AreaQue		    |
 *	v   +-----------------------+	    +-----------------------+
 */
LOCAL void appendFreeArea( MPLCB *mplcb, QUEUE *aq )
{
	QUEUE	*fq;
	INT	size = AreaSize(aq);

	/* Registration position search */
	/*  Search the free area whose size is equal to 'blksz',
	 *  or larger than 'blksz' but closest.
	 *  If it does not exist, return '&mplcb->freeque'.
	 */
	fq = searchFreeArea(mplcb, size);

	/* Register */
	clrAreaFlag(aq, AREA_USE);
	if ( fq != &mplcb->freeque && FreeSize(fq) == size ) {
		QueInsert(aq + 1, fq + 1);
	} else {
		QueInsert(aq + 1, fq);
	}
	QueInit(aq + 2);
}
Пример #11
0
/*
 * Registration of free area on FreeQue
 *	FreeQue is composed of 2 types: Queue that links the different
 *	size of areas by size 
 *	and queue that links the same size areas.
 *
 *	imacb->freeque
 *	|
 *	|  +-----------------------+	  +-----------------------+
 *	|  | AreaQue		   |	  | AreaQue		  |
 *	|  +-----------------------+	  +-----------------------+
 *	*---> FreeQue by size	   |  *----> FreeQue same size   ---->
 *	|  | FreeQue same size    ----*   | EmptyQue		  |
 *	|  |			   |	  |			  |
 *	|  |			   |	  |			  |
 *	|  +-----------------------+	  +-----------------------+
 *	|  | AreaQue		   |	  | AreaQue		  |
 *	v  +-----------------------+	  +-----------------------+
 */
LOCAL void appendFreeArea( QUEUE *aq, IMACB *imacb )
{
	QUEUE	*fq;
	size_t	size = AreaSize(aq);

	/* Registration position search */
	/*  Search free area whose size is equal to 'blksz',
	 *  or closest and larger than 'blksz'.
	 *  If it can not be found, return '&imacb->freeque'.
	 */
	fq = searchFreeArea(size, imacb);

	/* Registration */
	clrAreaFlag(aq, AREA_USE);
	if ( (fq != &imacb->freeque) && (FreeSize(fq) == size) ) {
		QueInsert(aq + 1, fq + 1);
	} else {
		QueInsert(aq + 1, fq);
	}
	QueInit(aq + 2);
}
Пример #12
0
void BufferFormatPrintTarget::WriteChar(char c)
{
    if (FreeSize() > 0)
        m_buffer[m_pos++] = c;
}
Пример #13
0
inline int BufferFormatPrintTarget::WritableSize(int expected) const
{
    return std::min(FreeSize(), expected);
}