diff --git a/source/dnode/vnode/impl/src/vnodeBufferPool.c b/source/dnode/vnode/impl/src/vnodeBufferPool.c index 49e7889517..6c1ededfc9 100644 --- a/source/dnode/vnode/impl/src/vnodeBufferPool.c +++ b/source/dnode/vnode/impl/src/vnodeBufferPool.c @@ -28,6 +28,9 @@ struct SVBufPool { SMemAllocatorFactory *pMAF; }; +static SMemAllocator *vBufPoolCreateMA(SMemAllocatorFactory *pMAF); +static void vBufPoolDestroyMA(SMemAllocatorFactory *pMAF, SMemAllocator *pMA); + int vnodeOpenBufPool(SVnode *pVnode) { uint64_t capacity; @@ -54,6 +57,15 @@ int vnodeOpenBufPool(SVnode *pVnode) { tDListAppend(&(pVnode->pBufPool->free), pVMA); } + pVnode->pBufPool->pMAF = (SMemAllocatorFactory *)malloc(sizeof(SMemAllocatorFactory)); + if (pVnode->pBufPool->pMAF == NULL) { + // TODO: handle error + return -1; + } + pVnode->pBufPool->pMAF->impl = pVnode; + pVnode->pBufPool->pMAF->create = vBufPoolCreateMA; + pVnode->pBufPool->pMAF->destroy = vBufPoolDestroyMA; + return 0; } @@ -127,195 +139,52 @@ bool vnodeBufPoolIsFull(SVnode *pVnode) { SMemAllocatorFactory *vBufPoolGetMAF(SVnode *pVnode) { return pVnode->pBufPool->pMAF; } -#if 0 - -typedef enum { - // Heap allocator - E_V_HEAP_ALLOCATOR = 0, - // Arena allocator - E_V_ARENA_ALLOCATOR -} EVMemAllocatorT; - +/* ------------------------ STATIC METHODS ------------------------ */ typedef struct { - /* TODO */ -} SVHeapAllocator; - -typedef struct SVArenaNode { - struct SVArenaNode *prev; - uint64_t size; - void * ptr; - char data[]; -} SVArenaNode; - -typedef struct { - uint64_t ssize; // step size - uint64_t lsize; // limit size - SVArenaNode *inuse; - SVArenaNode node; -} SVArenaAllocator; - -typedef struct { - SVnode * pVnode; - SListNode *pNode; + SVnode * pVnode; + SVMemAllocator *pVMA; } SVMAWrapper; +static FORCE_INLINE void *vmaMaloocCb(SMemAllocator *pMA, uint64_t size) { + SVMAWrapper *pWrapper = (SVMAWrapper *)(pMA->impl); -static SListNode * vBufPoolNewNode(uint64_t capacity, EVMemAllocatorT type); -static void vBufPoolFreeNode(SListNode *pNode); -static SMemAllocator *vBufPoolCreateMA(SMemAllocatorFactory *pmaf); -static void vBufPoolDestroyMA(SMemAllocatorFactory *pmaf, SMemAllocator *pma); -static void * vBufPoolMalloc(SVMemAllocator *pvma, uint64_t size); + return vmaMalloc(pWrapper->pVMA, size); +} -/* ------------------------ STATIC METHODS ------------------------ */ -static SListNode *vBufPoolNewNode(uint64_t capacity, EVMemAllocatorT type) { - SListNode * pNode; - SVMemAllocator *pvma; - uint64_t msize; - uint64_t ssize = 4096; // TODO - uint64_t lsize = 1024; // TODO +// TODO: Add atomic operations here +static SMemAllocator *vBufPoolCreateMA(SMemAllocatorFactory *pMAF) { + SMemAllocator *pMA; + SVnode * pVnode = (SVnode *)(pMAF->impl); + SVMAWrapper * pWrapper; - msize = sizeof(SListNode) + sizeof(SVMemAllocator); - if (type == E_V_ARENA_ALLOCATOR) { - msize += capacity; - } - - pNode = (SListNode *)calloc(1, msize); - if (pNode == NULL) { - // TODO: handle error + pMA = (SMemAllocator *)calloc(1, sizeof(*pMA) + sizeof(SVMAWrapper)); + if (pMA == NULL) { return NULL; } - pvma = (SVMemAllocator *)(pNode->data); - pvma->capacity = capacity; - pvma->type = type; + pVnode->pBufPool->inuse->_ref.val++; + pWrapper = POINTER_SHIFT(pMA, sizeof(*pMA)); + pWrapper->pVnode = pVnode; + pWrapper->pVMA = pVnode->pBufPool->inuse; - switch (type) { - case E_V_ARENA_ALLOCATOR: - vArenaAllocatorInit(&(pvma->vaa), capacity, ssize, lsize); - break; - case E_V_HEAP_ALLOCATOR: - // vHeapAllocatorInit(&(pvma->vha)); - break; - default: - ASSERT(0); - } + pMA->impl = pWrapper; + pMA->malloc = vmaMaloocCb; + pMA->calloc = NULL; + pMA->realloc = NULL; + pMA->free = NULL; + pMA->usage = NULL; - return pNode; + return pMA; } -static void vBufPoolFreeNode(SListNode *pNode) { - SVMemAllocator *pvma = (SVMemAllocator *)(pNode->data); +static void vBufPoolDestroyMA(SMemAllocatorFactory *pMAF, SMemAllocator *pMA) { + SVMAWrapper * pWrapper = (SVMAWrapper *)(pMA->impl); + SVnode * pVnode = pWrapper->pVnode; + SVMemAllocator *pVMA = pWrapper->pVMA; - switch (pvma->type) { - case E_V_ARENA_ALLOCATOR: - vArenaAllocatorClear(&(pvma->vaa)); - break; - case E_V_HEAP_ALLOCATOR: - // vHeapAllocatorClear(&(pvma->vha)); - break; - default: - break; + free(pMA); + if (--pVMA->_ref.val == 0) { + tDListPop(&(pVnode->pBufPool->incycle), pVMA); + tDListAppend(&(pVnode->pBufPool->free), pVMA); } - - free(pNode); -} - -static void *vBufPoolMalloc(SVMemAllocator *pvma, uint64_t size) { - void *ptr = NULL; - - if (pvma->type == E_V_ARENA_ALLOCATOR) { - SVArenaAllocator *pvaa = &(pvma->vaa); - - if (POINTER_DISTANCE(pvaa->inuse->ptr, pvaa->inuse->data) + size > pvaa->inuse->size) { - SVArenaNode *pNode = (SVArenaNode *)malloc(sizeof(*pNode) + MAX(size, pvaa->ssize)); - if (pNode == NULL) { - // TODO: handle error - return NULL; - } - - pNode->prev = pvaa->inuse; - pNode->size = MAX(size, pvaa->ssize); - pNode->ptr = pNode->data; - - pvaa->inuse = pNode; - } - - ptr = pvaa->inuse->ptr; - pvaa->inuse->ptr = POINTER_SHIFT(ptr, size); - } else if (pvma->type == E_V_HEAP_ALLOCATOR) { - /* TODO */ - } - - return ptr; -} - -static SMemAllocator *vBufPoolCreateMA(SMemAllocatorFactory *pmaf) { - SVnode * pVnode; - SMemAllocator * pma; - SVMemAllocator *pvma; - SVMAWrapper * pvmaw; - - pVnode = (SVnode *)(pmaf->impl); - pma = (SMemAllocator *)calloc(1, sizeof(*pma) + sizeof(SVMAWrapper)); - if (pma == NULL) { - // TODO: handle error - return NULL; - } - pvmaw = (SVMAWrapper *)POINTER_SHIFT(pma, sizeof(*pma)); - - // No allocator used currently - if (pVnode->pBufPool->inuse == NULL) { - while (listNEles(&(pVnode->pBufPool->free)) == 0) { - // TODO: wait until all released ro kill query - // tsem_wait(); - ASSERT(0); - } - - pVnode->pBufPool->inuse = tdListPopHead(&(pVnode->pBufPool->free)); - pvma = (SVMemAllocator *)(pVnode->pBufPool->inuse->data); - T_REF_INIT_VAL(pvma, 1); - } else { - pvma = (SVMemAllocator *)(pVnode->pBufPool->inuse->data); - } - - T_REF_INC(pvma); - - pvmaw->pVnode = pVnode; - pvmaw->pNode = pVnode->pBufPool->inuse; - - pma->impl = pvmaw; - pma->malloc = NULL; - pma->calloc = NULL; /* TODO */ - pma->realloc = NULL; /* TODO */ - pma->free = NULL; /* TODO */ - pma->usage = NULL; /* TODO */ - - return pma; -} - -static void vBufPoolDestroyMA(SMemAllocatorFactory *pmaf, SMemAllocator *pma) { /* TODO */ - SVnode * pVnode = (SVnode *)(pmaf->impl); - SListNode * pNode = ((SVMAWrapper *)(pma->impl))->pNode; - SVMemAllocator *pvma = (SVMemAllocator *)(pNode->data); - - if (T_REF_DEC(pvma) == 0) { - if (pvma->type == E_V_ARENA_ALLOCATOR) { - SVArenaAllocator *pvaa = &(pvma->vaa); - while (pvaa->inuse != &(pvaa->node)) { - SVArenaNode *pNode = pvaa->inuse; - pvaa->inuse = pNode->prev; - /* code */ - } - - pvaa->inuse->ptr = pvaa->inuse->data; - } else if (pvma->type == E_V_HEAP_ALLOCATOR) { - } else { - ASSERT(0); - } - - // Move node from incycle to free - tdListAppendNode(&(pVnode->pBufPool->free), tdListPopNode(&(pVnode->pBufPool->incycle), pNode)); - // tsem_post(); todo: sem_post - } -} -#endif \ No newline at end of file +} \ No newline at end of file