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; }
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; }