link-grammar-5.8.0/link-grammar/memory-pool.c
/**
 * Allocate an element from the requested pool.
 * This function uses the feature that pointers to void and char are
 * interchangeable.
 * 1. If no current block or current block exhausted - obtain another one
 *    and chain it the block chain. Else reuse an LRU unused block;
 *    The element pointer is aligned to the required alignment.
 * 2. Zero the block if required;
 * 3. Return element pointer.
 */
Allocate an element from the requested pool.
This function uses the feature that pointers to void and char are
interchangeable.
1. If no current block or current block exhausted - obtain another one
and chain it the block chain. Else reuse an LRU unused block;
The element pointer is aligned to the required alignment.
2. Zero the block if required;
3. Return element pointer.
Allocate an element from the requested pool . This function uses the feature that pointers to void and char are interchangeable . 1 . If no current block or current block exhausted - obtain another one and chain it the block chain . Else reuse an LRU unused block ; The element pointer is aligned to the required alignment . 2 . Zero the block if required ; 3 . Return element pointer .
void *pool_alloc(Pool_desc *mp)
{
	mp->curr_elements++; 
#ifdef POOL_FREE
	if (NULL != mp->free_list)
	{
		void *alloc_next = mp->free_list;
		ASAN_UNPOISON_MEMORY_REGION(alloc_next, mp->element_size);
		mp->free_list = *(char **)mp->free_list;
		if (mp->zero_out) memset(alloc_next, 0, mp->element_size);
		return alloc_next;
	}
#endif 
	if ((NULL == mp->alloc_next) || (mp->alloc_next == mp->ring + mp->data_size))
	{
#ifdef POOL_EXACT
		assert(!mp->exact || (NULL == mp->alloc_next),
				 "Too many elements %zu>%zu (pool '%s' created in %s())",
				 mp->curr_elements, mp->num_elements, mp->name, mp->func);
#endif 
		char *prev = mp->ring; 
		if (NULL != mp->ring)
		{
			mp->ring = POOL_NEXT_BLOCK(mp->ring, mp->data_size);
		}
		if (NULL == mp->ring)
		{
			mp->ring = aligned_alloc(mp->alignment, mp->block_size);
			if (NULL == mp->ring)
			{
				char errbuf[64];
				lg_strerror(errno, errbuf, sizeof(errbuf));
				prt_error("Fatal error: aligned_alloc(%zu, %zu): %s",
				          mp->block_size, mp->element_size, errbuf);
				exit(1);
			}
			if (NULL == mp->alloc_next)
				mp->chain = mp->ring; 
			else
				POOL_NEXT_BLOCK(prev, mp->data_size) = mp->ring;
			POOL_NEXT_BLOCK(mp->ring, mp->data_size) = NULL;
		} 
		if (mp->zero_out) memset(mp->ring, 0, mp->data_size);
		mp->alloc_next = mp->ring;
	}
	void *alloc_next = mp->alloc_next;
	mp->alloc_next += mp->element_size;
	return alloc_next;
}
void * pool_alloc ( Pool_desc * mp ) { mp -> curr_elements ++ ; #ifdef POOL_FREE if ( NULL != mp -> free_list ) { void * alloc_next = mp -> free_list ; ASAN_UNPOISON_MEMORY_REGION ( alloc_next , mp -> element_size ) ; mp -> free_list = * ( char * * ) mp -> free_list ; if ( mp -> zero_out ) memset ( alloc_next , 0 , mp -> element_size ) ; return alloc_next ; } #endif if ( ( NULL == mp -> alloc_next ) || ( mp -> alloc_next == mp -> ring + mp -> data_size ) ) { #ifdef POOL_EXACT assert ( ! mp -> exact || ( NULL == mp -> alloc_next ) , " " , mp -> curr_elements , mp -> num_elements , mp -> name , mp -> func ) ; #endif char * prev = mp -> ring ; if ( NULL != mp -> ring ) { mp -> ring = POOL_NEXT_BLOCK ( mp -> ring , mp -> data_size ) ; } if ( NULL == mp -> ring ) { mp -> ring = aligned_alloc ( mp -> alignment , mp -> block_size ) ; if ( NULL == mp -> ring ) { char errbuf [ 64 ] ; lg_strerror ( errno , errbuf , sizeof ( errbuf ) ) ; prt_error ( " " , mp -> block_size , mp -> element_size , errbuf ) ; exit ( 1 ) ; } if ( NULL == mp -> alloc_next ) mp -> chain = mp -> ring ; else POOL_NEXT_BLOCK ( prev , mp -> data_size ) = mp -> ring ; POOL_NEXT_BLOCK ( mp -> ring , mp -> data_size ) = NULL ; } if ( mp -> zero_out ) memset ( mp -> ring , 0 , mp -> data_size ) ; mp -> alloc_next = mp -> ring ; } void * alloc_next = mp -> alloc_next ; mp -> alloc_next += mp -> element_size ; return alloc_next ; }
Allocate an element from the requested pool.
Allocate an element from the requested pool .
/* For stats. */ // POOL_FREE /* POOL_EXACT */ /* No current block or current block exhausted - obtain another one. */ /* Remember current block for possible chaining. */ /* Next block already exists. */ /* Allocate a new block and chain it. */ /* aligned_alloc() has strict requirements. */ /* This is the start of the chain. */ //printf("New ring %p next %p\n", mp->ring, //POOL_NEXT_BLOCK(mp->ring, mp->data_size)); /* Else reuse existing block. */ /* Grab a new element. */