Exemplo n.º 1
0
void mem_pool::pool_free( void* ptr, size_t bytes )
{
    if( ptr )
        pool_dealloc( ptr, bytes );

    if( bytes <= MEMORY_POOL_MAX )
    {
        int i;
        size_t index = LIST_INDEX( bytes );
        size_t blk_count = BLOCK_COUNT( index );
        mempage_t *erase = NULL, *prev = NULL, *curr = pool[index].first;

        if( pool_lock )
            pool_lock( index );

        while( curr )
        {
            if( curr->count != blk_count ) /* 判断是否是空闲页 */
            {
                prev = curr;
                curr = curr->next;
            }
            else
            {
                /* 从页面缓存中退出 */
                for( i = 0; i < MEMORY_POOL_BUFFER; ++i )
                {
                    if( pool[index].buffer[i] == curr )
                    {
                        pool[index].buffer[i] = NULL;
                        break;
                    }
                }

                if( prev )
                    prev->next = curr->next; /* 空闲页不在链首 */
                else
                    pool[index].first = curr->next; /* 空闲页在链首 */

                /* 将空闲页释放 */
                erase = curr;
                curr = curr->next;
                MEMFREE( erase );
                --( pool[index].useable );
            } /* end if */
        } /* end while */

        if( pool_unlock )
            pool_unlock( index );
    }
}
int _gnix_buddy_alloc(gnix_buddy_alloc_handle_t *alloc_handle, void **ptr,
		      uint32_t len)
{
	uint32_t block_size, i = 0;

	GNIX_TRACE(FI_LOG_EP_CTRL, "\n");

	if (unlikely(!alloc_handle || !ptr || !len ||
		     len > alloc_handle->max)) {

		GNIX_WARN(FI_LOG_EP_CTRL,
			  "Invalid parameter to _gnix_buddy_alloc.\n");
		return -FI_EINVAL;
	}

	block_size = BLOCK_SIZE(len, MIN_BLOCK_SIZE);
	i = (uint32_t) LIST_INDEX(block_size, MIN_BLOCK_SIZE);

	fastlock_acquire(&alloc_handle->lock);

	if (__gnix_buddy_find_block(alloc_handle, i, ptr)) {
		fastlock_release(&alloc_handle->lock);
		GNIX_WARN(FI_LOG_EP_CTRL,
			  "Could not allocate buddy block.\n");
		return -FI_ENOMEM;
	}

	fastlock_release(&alloc_handle->lock);

	_gnix_set_bit(&alloc_handle->bitmap,
		      __gnix_buddy_bitmap_index(*ptr, block_size,
						alloc_handle->base,
						alloc_handle->len,
						MIN_BLOCK_SIZE));

	return FI_SUCCESS;
}
int _gnix_buddy_free(gnix_buddy_alloc_handle_t *alloc_handle, void *ptr,
		     uint32_t len)
{
	uint32_t block_size;

	GNIX_TRACE(FI_LOG_EP_CTRL, "\n");

	if (unlikely(!alloc_handle || !len || len > alloc_handle->max ||
		     ptr >= (void *) ((uint8_t *) alloc_handle->base +
				      alloc_handle->len) ||
		     ptr < alloc_handle->base)) {

		GNIX_WARN(FI_LOG_EP_CTRL,
			  "Invalid parameter to _gnix_buddy_free.\n");
		return -FI_EINVAL;
	}

	block_size = BLOCK_SIZE(len, MIN_BLOCK_SIZE);

	_gnix_clear_bit(&alloc_handle->bitmap,
			__gnix_buddy_bitmap_index(ptr, block_size,
						  alloc_handle->base,
						  alloc_handle->len,
						  MIN_BLOCK_SIZE));

	fastlock_acquire(&alloc_handle->lock);

	block_size = __gnix_buddy_coalesce(alloc_handle, &ptr, block_size);

	dlist_insert_tail(ptr, alloc_handle->lists +
			  LIST_INDEX(block_size, MIN_BLOCK_SIZE));

	fastlock_release(&alloc_handle->lock);

	return FI_SUCCESS;
}
Exemplo n.º 4
0
void mem_pool::pool_dealloc( void* ptr, size_t bytes )
{
    if( !ptr )
        return;

    if( bytes <= MEMORY_POOL_MAX )
    {
        size_t index = LIST_INDEX( bytes );
        mempage_t *curr, *prev = NULL;
        unsigned char *begin, *end, *blk = (unsigned char*)ptr;

        if( pool_lock )
            pool_lock( index );

        curr = pool[index].first;

        while( curr )
        {
            begin = (unsigned char*)curr + sizeof(mempage_t);
            end = begin + pool[index].page_size;
            if( blk < begin || blk >= end ) /* 判断ptr是否在当前页内 */
            {
                prev = curr;
                curr = curr->next;
            }
            else
            {
                size_t blk_size = BLOCK_SIZE( index );

                /* 检查ptr是否正确 */
                if( (blk - begin) % blk_size == 0 )
                {
                    /* 将内存块回收至链表首部 */
                    memblk_t* pblk = (memblk_t*)ptr;
                    pblk->next = curr->free;
                    curr->free = pblk;

                    /* 如果回收前内存页已满,则将可用页数加一 */
                    if( curr->count == 0 )
                        ++( pool[index].useable );
                    ++( curr->count );

                    /* 如果当前页不在链首,则将之移至链首 */
                    if( pool[index].first != curr )
                    {
                        prev->next = curr->next;
                        curr->next = pool[index].first;
                        pool[index].first = curr;
                    }

                    ++pool_dealloc_count;
                }
                break;
            } /* end else */
        } /* end while */

        if( pool_unlock )
            pool_unlock( index );

        return;
    } /* end if */

    /* ptr不是由内存池分配 */
    MEMFREE( ptr );
    ++pool_dealloc_count;
}
Exemplo n.º 5
0
void* mem_pool::pool_alloc( size_t bytes )
{
    void* ptr = NULL;

    if( bytes > MEMORY_POOL_MAX )
    {
        ptr = MEMALLOC( bytes );
    }
    else
    {
        size_t index = LIST_INDEX( bytes );

        if( pool_lock )
            pool_lock( index );

        if( pool[index].first && pool[index].useable > 0 )
        {
            int i;
            mempage_t *prev = NULL, *curr = NULL;

            /* 先查找页面缓存 */
            for( i = 0; i < MEMORY_POOL_BUFFER; ++i )
            {
                if( pool[index].buffer[i] )
                {
                    ptr = pool[index].buffer[i]->free;
                    pool[index].buffer[i]->free = pool[index].buffer[i]->free->next;
                    --( pool[index].buffer[i]->count );

                    /* 如果该页已无空闲块,则将该页自页面缓存中退出 */
                    if( pool[index].buffer[i]->count == 0 )
                    {
                        --( pool[index].useable );
                        pool[index].buffer[i] = NULL;
                    }
                    else
                    {
                        if( i > 0 )
                        {
                            /* 如果该页不在缓存首,则将该页调整至缓存首 */
                            pool[index].buffer[0] = pool[index].buffer[i];
                            pool[index].buffer[i] = NULL;
                        }
                    }

                    goto EXIT_POOL_ALLOC;
                }
            } /* end for */

            /* 页面缓存为空,则遍历链中的所有内存页寻找空闲的内存块 */
            curr = pool[index].first;
            while( curr )
            {
                if( curr->count == 0 ) /* 该页中没有空闲块 */
                {
                    /* 进入下一页 */
                    prev = curr;
                    curr = curr->next;
                }
                else /* 该页中有空闲块 */
                {
                    size_t page_count = 0; /* 统计遍历过的可用内存页 */
                    ptr = curr->free;
                    curr->free = curr->free->next;
                    --( curr->count );
                    if( curr->count == 0 )
                        --( pool[index].useable );

                    /* 继续遍历链表,寻找其他还有空闲块的页面,将之放入页面缓存 */
                    while( curr && page_count < pool[index].useable )
                    {
                        if( curr->count != 0 )
                        {
                            /* 页面缓存还有位置则放入页面缓存 */
                            if( page_count < MEMORY_POOL_BUFFER )
                                pool[index].buffer[page_count] = curr;

                            ++page_count;

                            /* 如果当前页未满并且不在链首,则将之移至链首 */
                            if( pool[index].first != curr )
                            {
                                prev->next = curr->next; /* 保存下一页 */
                                curr->next = pool[index].first;
                                pool[index].first = curr;
                                curr = prev->next; /* 进入下一页 */
                                continue;
                            }
                        }

                        /* 进入下一页 */
                        prev = curr;
                        curr = curr->next;
                    }

                    goto EXIT_POOL_ALLOC;
                } /* end else */
            } /* end while */
        } /* end if pool[index].useable > 0 */
        else
        {
            /* 该链下未分配内存页或无空闲块,此时需增加新的内存页 */
            mempage_t* pg = NULL;
            size_t blk_size = BLOCK_SIZE( index );

            /* 如果 page_size = 0,则计算该内存链下每个内存页需占用的字节数 */
            if( 0 == pool[index].page_size )
            {
                if( DEFAULT_PAGE_SIZE % blk_size == 0 )
                    pool[index].page_size = DEFAULT_PAGE_SIZE;
                else
                    pool[index].page_size = (DEFAULT_PAGE_SIZE / blk_size)
                                            * blk_size;
            }

            pg = (mempage_t*)MEMALLOC( sizeof(mempage_t)
                                       + pool[index].page_size );

            if( pg )
            {
                memblk_t* curr = NULL;
                size_t i, blk_count = BLOCK_COUNT( index );

                pg->next = pool[index].first;
                pool[index].first = pg;

                 /* 将内存页中的所有内存块串联成一个链表 */
                curr = (memblk_t*)((unsigned char*)pg + sizeof(mempage_t));
                pg->free = curr;
                for( i = 1; i < blk_count; ++i )
                {
                    curr->next = (memblk_t*)((unsigned char*)curr + blk_size);
                    curr = curr->next;
                }
                curr->next = NULL;

                ptr = pg->free;
                pg->free = pg->free->next;
                pg->count = blk_count - 1;
                ++( pool[index].useable );
                pool[index].buffer[0] = pg;
            }
        }

EXIT_POOL_ALLOC:
        if( pool_unlock )
            pool_unlock( index );
    } /* end else */

    if( ptr )
        ++pool_alloc_count;

    return ptr;
}