TDengine/source/dnode/vnode/src/vnd/vnodeBufPool.c

197 lines
5.4 KiB
C
Raw Normal View History

2022-04-14 08:42:50 +00:00
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
2022-04-26 11:04:26 +00:00
#include "vnd.h"
2022-04-14 08:42:50 +00:00
/* ------------------------ STRUCTURES ------------------------ */
2022-10-09 05:52:44 +00:00
#define VNODE_BUFPOOL_SEGMENTS 3
2022-04-14 08:42:50 +00:00
2022-10-09 05:52:44 +00:00
static int vnodeBufPoolCreate(SVnode *pVnode, int64_t size, SVBufPool **ppPool) {
SVBufPool *pPool;
pPool = taosMemoryMalloc(sizeof(SVBufPool) + size);
if (pPool == NULL) {
terrno = TSDB_CODE_OUT_OF_MEMORY;
return -1;
}
2022-11-11 05:53:16 +00:00
if (VND_IS_RSMA(pVnode)) {
if (taosThreadSpinInit(pPool->lock, 0) != 0) {
taosMemoryFree(pPool);
terrno = TAOS_SYSTEM_ERROR(errno);
return -1;
}
} else {
pPool->lock = NULL;
2022-10-09 05:52:44 +00:00
}
pPool->next = NULL;
pPool->pVnode = pVnode;
pPool->nRef = 0;
pPool->size = 0;
pPool->ptr = pPool->node.data;
pPool->pTail = &pPool->node;
pPool->node.prev = NULL;
pPool->node.pnext = &pPool->pTail;
pPool->node.size = size;
2022-04-14 08:42:50 +00:00
2022-10-09 05:52:44 +00:00
*ppPool = pPool;
return 0;
}
static int vnodeBufPoolDestroy(SVBufPool *pPool) {
vnodeBufPoolReset(pPool);
2022-11-11 05:53:16 +00:00
if (pPool->lock) taosThreadSpinDestroy(pPool->lock);
2022-10-09 05:52:44 +00:00
taosMemoryFree(pPool);
return 0;
}
int vnodeOpenBufPool(SVnode *pVnode) {
2022-04-14 08:42:50 +00:00
SVBufPool *pPool = NULL;
2022-10-09 05:52:44 +00:00
int64_t size = pVnode->config.szBuf / VNODE_BUFPOOL_SEGMENTS;
2022-04-14 08:42:50 +00:00
ASSERT(pVnode->pPool == NULL);
for (int i = 0; i < 3; i++) {
// create pool
2022-10-09 05:52:44 +00:00
if (vnodeBufPoolCreate(pVnode, size, &pPool)) {
2022-06-02 05:57:39 +00:00
vError("vgId:%d, failed to open vnode buffer pool since %s", TD_VID(pVnode), tstrerror(terrno));
2022-04-14 08:42:50 +00:00
vnodeCloseBufPool(pVnode);
return -1;
}
2022-04-20 06:56:34 +00:00
// add pool to vnode
2022-04-14 08:42:50 +00:00
pPool->next = pVnode->pPool;
pVnode->pPool = pPool;
}
2022-08-02 07:57:37 +00:00
vDebug("vgId:%d, vnode buffer pool is opened, size:%" PRId64, TD_VID(pVnode), size);
2022-04-14 08:42:50 +00:00
return 0;
}
int vnodeCloseBufPool(SVnode *pVnode) {
SVBufPool *pPool;
for (pPool = pVnode->pPool; pPool; pPool = pVnode->pPool) {
pVnode->pPool = pPool->next;
vnodeBufPoolDestroy(pPool);
}
if (pVnode->inUse) {
vnodeBufPoolDestroy(pVnode->inUse);
pVnode->inUse = NULL;
}
2022-06-02 05:57:39 +00:00
vDebug("vgId:%d, vnode buffer pool is closed", TD_VID(pVnode));
2022-04-14 08:42:50 +00:00
return 0;
}
void vnodeBufPoolReset(SVBufPool *pPool) {
2022-10-09 05:52:44 +00:00
for (SVBufPoolNode *pNode = pPool->pTail; pNode->prev; pNode = pPool->pTail) {
2022-04-14 08:42:50 +00:00
ASSERT(pNode->pnext == &pPool->pTail);
pNode->prev->pnext = &pPool->pTail;
pPool->pTail = pNode->prev;
pPool->size = pPool->size - sizeof(*pNode) - pNode->size;
taosMemoryFree(pNode);
}
ASSERT(pPool->size == pPool->ptr - pPool->node.data);
pPool->size = 0;
pPool->ptr = pPool->node.data;
}
2022-04-20 06:56:34 +00:00
void *vnodeBufPoolMalloc(SVBufPool *pPool, int size) {
2022-04-14 08:42:50 +00:00
SVBufPoolNode *pNode;
2022-10-09 05:52:44 +00:00
void *p = NULL;
ASSERT(pPool != NULL);
2022-11-11 05:53:16 +00:00
if(pPool->lock) taosThreadSpinLock(pPool->lock);
2022-04-14 08:42:50 +00:00
if (pPool->node.size >= pPool->ptr - pPool->node.data + size) {
// allocate from the anchor node
p = pPool->ptr;
pPool->ptr = pPool->ptr + size;
pPool->size += size;
} else {
// allocate a new node
pNode = taosMemoryMalloc(sizeof(*pNode) + size);
if (pNode == NULL) {
terrno = TSDB_CODE_OUT_OF_MEMORY;
2022-11-11 05:53:16 +00:00
if (pPool->lock) taosThreadSpinUnlock(pPool->lock);
2022-04-14 08:42:50 +00:00
return NULL;
}
p = pNode->data;
pNode->size = size;
pNode->prev = pPool->pTail;
pNode->pnext = &pPool->pTail;
pPool->pTail->pnext = &pNode->prev;
pPool->pTail = pNode;
pPool->size = pPool->size + sizeof(*pNode) + size;
}
2022-11-11 05:53:16 +00:00
if(pPool->lock) taosThreadSpinUnlock(pPool->lock);
2022-04-14 08:42:50 +00:00
return p;
}
void vnodeBufPoolFree(SVBufPool *pPool, void *p) {
2022-10-14 05:34:25 +00:00
// uint8_t *ptr = (uint8_t *)p;
// SVBufPoolNode *pNode;
2022-04-14 08:42:50 +00:00
2022-10-14 05:34:25 +00:00
// if (ptr < pPool->node.data || ptr >= pPool->node.data + pPool->node.size) {
// pNode = &((SVBufPoolNode *)p)[-1];
// *pNode->pnext = pNode->prev;
// pNode->prev->pnext = pNode->pnext;
2022-04-14 08:42:50 +00:00
2022-10-14 05:34:25 +00:00
// pPool->size = pPool->size - sizeof(*pNode) - pNode->size;
// taosMemoryFree(pNode);
// }
2022-04-14 08:42:50 +00:00
}
2022-07-19 08:30:49 +00:00
void vnodeBufPoolRef(SVBufPool *pPool) {
int32_t nRef = atomic_fetch_add_32(&pPool->nRef, 1);
ASSERT(nRef > 0);
}
void vnodeBufPoolUnRef(SVBufPool *pPool) {
int32_t nRef = atomic_sub_fetch_32(&pPool->nRef, 1);
if (nRef == 0) {
SVnode *pVnode = pPool->pVnode;
vnodeBufPoolReset(pPool);
taosThreadMutexLock(&pVnode->mutex);
2022-10-09 05:52:44 +00:00
int64_t size = pVnode->config.szBuf / VNODE_BUFPOOL_SEGMENTS;
if (pPool->node.size != size) {
SVBufPool *pPoolT = NULL;
if (vnodeBufPoolCreate(pVnode, size, &pPoolT) < 0) {
2022-10-21 02:39:19 +00:00
vWarn("vgId:%d, try to change buf pools size from %" PRId64 " to %" PRId64 " since %s", TD_VID(pVnode),
2022-10-09 05:52:44 +00:00
pPool->node.size, size, tstrerror(errno));
} else {
vnodeBufPoolDestroy(pPool);
pPool = pPoolT;
2022-10-21 02:39:19 +00:00
vDebug("vgId:%d, change buf pools size from %" PRId64 " to %" PRId64, TD_VID(pVnode), pPool->node.size, size);
2022-10-09 05:52:44 +00:00
}
}
2022-07-19 08:30:49 +00:00
pPool->next = pVnode->pPool;
pVnode->pPool = pPool;
taosThreadCondSignal(&pVnode->poolNotEmpty);
taosThreadMutexUnlock(&pVnode->mutex);
}
}