コード例 #1
0
ファイル: RingBuffer.c プロジェクト: 190235047/swoole-src
static void* swRingBuffer_alloc(swMemoryPool *pool, uint32_t size)
{
    assert(size > 0);

    swRingBuffer *object = pool->object;
    swRingBuffer_item *item;
    uint32_t capacity;

    uint32_t alloc_size = size + sizeof(swRingBuffer_item);

    if (object->free_count > 0)
    {
        swRingBuffer_collect(object);
    }

    if (object->status == 0)
    {
        if (object->alloc_offset + alloc_size >= object->size)
        {
            uint32_t skip_n = object->size - object->alloc_offset;

            item = object->memory + object->alloc_offset;
            item->lock = 0;
            item->length = skip_n - sizeof(swRingBuffer_item);

            sw_atomic_t *free_count = &object->free_count;
            sw_atomic_fetch_add(free_count, 1);

            object->alloc_offset = 0;
            object->status = 1;

            capacity = object->collect_offset - object->alloc_offset;
        }
        else
        {
            capacity = object->size - object->alloc_offset;
        }
    }
    else
    {
        capacity = object->collect_offset - object->alloc_offset;
    }

    if (capacity < alloc_size)
    {
        return NULL;
    }

    item = object->memory + object->alloc_offset;
    item->lock = 1;
    item->length = size;
    item->index = object->alloc_count;

    object->alloc_offset += alloc_size;
    object->alloc_count ++;

    swDebug("alloc: ptr=%d", (void *)item->data - object->memory);

    return item->data;
}
コード例 #2
0
ファイル: RingBuffer.c プロジェクト: jhfnetboy/swoole
static void* swRingBuffer_alloc(swMemoryPool *pool, uint32_t size)
{
    swRingBuffer *object = pool->object;
    swRingBuffer_head *item;
    size_t n;
    uint8_t try_collect = 0;
    void *ret_mem = NULL;

    swTraceLog(SW_TRACE_MEMORY, "[0] alloc_offset=%ld|collect_offset=%ld", object->alloc_offset, object->collect_offset);

start_alloc:

    if (object->alloc_offset < object->collect_offset)
    {
head_alloc:
        item = object->memory + object->alloc_offset;
        /**
         * 剩余内存的长度
         */
        n = object->collect_offset - object->alloc_offset;
        /**
         * 剩余内存可供本次分配,必须是>size
         */
        if ((n - sizeof(swRingBuffer_head)) > size)
        {
            goto do_alloc;
        }
        /**
         * 内存不足,已尝试回收过
         */
        else if (try_collect == 1)
        {
            swWarn("alloc_offset=%ld|collect_offset=%ld", object->alloc_offset, object->collect_offset);
            return NULL;
        }
        //try collect memory, then try head_alloc
        else
        {
            try_collect = 1;
            swRingBuffer_collect(object);
            goto start_alloc;
        }
    }
    else
    {
        //tail_alloc:
        n = object->size - object->alloc_offset;
        item = object->memory + object->alloc_offset;

        swTraceLog(SW_TRACE_MEMORY, "[1] size=%ld, ac_size=%d, n_size=%ld", object->size, size, n);

        if ((n - sizeof(swRingBuffer_head)) >= size)
        {
            goto do_alloc;
        }
        else
        {
            //unlock
            item->lock = 0;
            item->length = n - sizeof(swRingBuffer_head);

            //goto head
            object->alloc_offset = 0;

            swTraceLog(SW_TRACE_MEMORY, "switch to head_alloc. ac_size=%d, n_size=%ld", size, n);

            goto head_alloc;
        }
    }

do_alloc:
    item->lock = 1;
    item->length = size;
    ret_mem = (void*) (object->memory + object->alloc_offset + sizeof(swRingBuffer_head));

    /**
     * 内存游标向后移动
     */
    object->alloc_offset += size + sizeof(swRingBuffer_head);

    if (object->free_n > 0)
    {
        swRingBuffer_collect(object);
    }

    return ret_mem;
}