You've already forked qlg.tsgz.moe
Init Repo
This commit is contained in:
211
vendor/swoole/src/memory/RingBuffer.c
vendored
Executable file
211
vendor/swoole/src/memory/RingBuffer.c
vendored
Executable file
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Swoole |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 2.0 of the Apache license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.apache.org/licenses/LICENSE-2.0.html |
|
||||
| If you did not receive a copy of the Apache2.0 license and are unable|
|
||||
| to obtain it through the world-wide-web, please send a note to |
|
||||
| license@swoole.com so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author: Tianfeng Han <mikan.tenny@gmail.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#include "swoole.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t shared;
|
||||
uint8_t status;
|
||||
uint32_t size;
|
||||
uint32_t alloc_offset;
|
||||
uint32_t collect_offset;
|
||||
uint32_t alloc_count;
|
||||
sw_atomic_t free_count;
|
||||
void *memory;
|
||||
} swRingBuffer;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t lock;
|
||||
uint16_t index;
|
||||
uint32_t length;
|
||||
char data[0];
|
||||
} swRingBuffer_item;
|
||||
|
||||
static void swRingBuffer_destory(swMemoryPool *pool);
|
||||
static void* swRingBuffer_alloc(swMemoryPool *pool, uint32_t size);
|
||||
static void swRingBuffer_free(swMemoryPool *pool, void *ptr);
|
||||
|
||||
#ifdef SW_RINGBUFFER_DEBUG
|
||||
static void swRingBuffer_print(swRingBuffer *object, char *prefix);
|
||||
|
||||
static void swRingBuffer_print(swRingBuffer *object, char *prefix)
|
||||
{
|
||||
printf("%s: size=%d, status=%d, alloc_count=%d, free_count=%d, offset=%d, next_offset=%d\n", prefix, object->size,
|
||||
object->status, object->alloc_count, object->free_count, object->alloc_offset, object->collect_offset);
|
||||
}
|
||||
#endif
|
||||
|
||||
swMemoryPool *swRingBuffer_new(uint32_t size, uint8_t shared)
|
||||
{
|
||||
void *mem = (shared == 1) ? sw_shm_malloc(size) : sw_malloc(size);
|
||||
if (mem == NULL)
|
||||
{
|
||||
swWarn("malloc(%d) failed.", size);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
swRingBuffer *object = mem;
|
||||
mem += sizeof(swRingBuffer);
|
||||
bzero(object, sizeof(swRingBuffer));
|
||||
|
||||
object->size = (size - sizeof(swRingBuffer) - sizeof(swMemoryPool));
|
||||
object->shared = shared;
|
||||
|
||||
swMemoryPool *pool = mem;
|
||||
mem += sizeof(swMemoryPool);
|
||||
|
||||
pool->object = object;
|
||||
pool->destroy = swRingBuffer_destory;
|
||||
pool->free = swRingBuffer_free;
|
||||
pool->alloc = swRingBuffer_alloc;
|
||||
|
||||
object->memory = mem;
|
||||
|
||||
swDebug("memory: ptr=%p", mem);
|
||||
|
||||
return pool;
|
||||
}
|
||||
|
||||
static void swRingBuffer_collect(swRingBuffer *object)
|
||||
{
|
||||
swRingBuffer_item *item;
|
||||
sw_atomic_t *free_count = &object->free_count;
|
||||
|
||||
int count = object->free_count;
|
||||
int i;
|
||||
uint32_t n_size;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
item = object->memory + object->collect_offset;
|
||||
if (item->lock == 0)
|
||||
{
|
||||
n_size = item->length + sizeof(swRingBuffer_item);
|
||||
|
||||
object->collect_offset += n_size;
|
||||
|
||||
if (object->collect_offset + sizeof(swRingBuffer_item) >object->size || object->collect_offset >= object->size)
|
||||
{
|
||||
object->collect_offset = 0;
|
||||
object->status = 0;
|
||||
}
|
||||
sw_atomic_fetch_sub(free_count, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 - sizeof(swRingBuffer_item)))
|
||||
{
|
||||
uint32_t skip_n = object->size - object->alloc_offset;
|
||||
if (skip_n >= sizeof(swRingBuffer_item))
|
||||
{
|
||||
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=%p", (void * )((void * )item->data - object->memory));
|
||||
|
||||
return item->data;
|
||||
}
|
||||
|
||||
static void swRingBuffer_free(swMemoryPool *pool, void *ptr)
|
||||
{
|
||||
swRingBuffer *object = pool->object;
|
||||
swRingBuffer_item *item = ptr - sizeof(swRingBuffer_item);
|
||||
|
||||
assert(ptr >= object->memory);
|
||||
assert(ptr <= object->memory + object->size);
|
||||
assert(item->lock == 1);
|
||||
|
||||
if (item->lock != 1)
|
||||
{
|
||||
swDebug("invalid free: index=%d, ptr=%p", item->index, (void * )((void * )item->data - object->memory));
|
||||
}
|
||||
else
|
||||
{
|
||||
item->lock = 0;
|
||||
}
|
||||
|
||||
swDebug("free: ptr=%p", (void * )((void * )item->data - object->memory));
|
||||
|
||||
sw_atomic_t *free_count = &object->free_count;
|
||||
sw_atomic_fetch_add(free_count, 1);
|
||||
}
|
||||
|
||||
static void swRingBuffer_destory(swMemoryPool *pool)
|
||||
{
|
||||
swRingBuffer *object = pool->object;
|
||||
if (object->shared)
|
||||
{
|
||||
sw_shm_free(object);
|
||||
}
|
||||
else
|
||||
{
|
||||
sw_free(object);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user