enh: optimize source code
This commit is contained in:
parent
08ec404200
commit
07034ce28c
|
@ -31,27 +31,26 @@ typedef enum MemPoolEvictPolicy {
|
|||
E_EVICT_MAX_VALUE, // no used
|
||||
} MemPoolEvictPolicy;
|
||||
|
||||
typedef enum MemPoolUsageLevel {
|
||||
E_MEM_USAGE_LOW = 0,
|
||||
E_MEM_USAGE_MIDDLE,
|
||||
E_MEM_USAGE_HIGH,
|
||||
E_MEM_USAGE_EXTRAME,
|
||||
E_MEM_USAGE_MAX_VALUE
|
||||
} MemPoolUsageLevel;
|
||||
typedef struct SMemPoolJob {
|
||||
uint64_t jobId;
|
||||
int64_t allocMemSize;
|
||||
int64_t maxAllocMemSize;
|
||||
} SMemPoolJob;
|
||||
|
||||
|
||||
typedef void (*mpDecConcSessionNum)(void);
|
||||
typedef void (*mpIncConcSessionNum)(void);
|
||||
typedef void (*mpSetConcSessionNum)(int32_t);
|
||||
typedef void (*mpRetireCollections)(int64_t, bool);
|
||||
typedef void (*mpRetireCollection)(uint64_t);
|
||||
typedef void (*mpRetireJobs)(int64_t, bool, int32_t);
|
||||
typedef void (*mpRetireJob)(SMemPoolJob*, int32_t);
|
||||
typedef void (*mpCfgUpdate)(void*, void*);
|
||||
|
||||
typedef struct SMemPoolCallBack {
|
||||
mpDecConcSessionNum decSessFp;
|
||||
mpIncConcSessionNum incSessFp;
|
||||
mpSetConcSessionNum setSessFp;
|
||||
mpRetireCollections retiresFp;
|
||||
mpRetireCollection retireFp;
|
||||
mpRetireJobs retireJobsFp;
|
||||
mpRetireJob retireJobFp;
|
||||
mpCfgUpdate cfgUpdateFp;
|
||||
} SMemPoolCallBack;
|
||||
|
||||
|
@ -59,24 +58,13 @@ typedef struct SMemPoolCallBack {
|
|||
typedef struct SMemPoolCfg {
|
||||
bool autoMaxSize;
|
||||
int64_t maxSize;
|
||||
int64_t sessionExpectSize;
|
||||
int64_t collectionQuota;
|
||||
int64_t jobQuota;
|
||||
int32_t chunkSize;
|
||||
int32_t threadNum;
|
||||
int8_t usageLevel[E_MEM_USAGE_MAX_VALUE];
|
||||
MemPoolEvictPolicy evicPolicy;
|
||||
SMemPoolCallBack cb;
|
||||
} SMemPoolCfg;
|
||||
|
||||
typedef struct SMemPoolCollection {
|
||||
uint64_t collectionId;
|
||||
int64_t allocMemSize;
|
||||
int64_t maxAllocMemSize;
|
||||
} SMemPoolCollection;
|
||||
|
||||
|
||||
|
||||
void taosMemPoolModInit(void);
|
||||
int32_t taosMemPoolOpen(char* poolName, SMemPoolCfg* cfg, void** poolHandle);
|
||||
void *taosMemPoolMalloc(void* poolHandle, void* session, int64_t size, char* fileName, int32_t lineNo);
|
||||
void *taosMemPoolCalloc(void* poolHandle, void* session, int64_t num, int64_t size, char* fileName, int32_t lineNo);
|
||||
|
@ -89,9 +77,9 @@ void *taosMemPoolMallocAlign(void* poolHandle, void* session, uint32_t alignme
|
|||
void taosMemPoolClose(void* poolHandle);
|
||||
void taosMemPoolModDestroy(void);
|
||||
void taosAutoMemoryFree(void *ptr);
|
||||
int32_t taosMemPoolInitSession(void* poolHandle, void** ppSession, void* pCollection);
|
||||
int32_t taosMemPoolInitSession(void* poolHandle, void** ppSession, void* pJob);
|
||||
void taosMemPoolDestroySession(void* poolHandle, void* session);
|
||||
int32_t taosMemPoolCallocCollection(uint64_t collectionId, void** ppCollection);
|
||||
int32_t taosMemPoolCallocJob(uint64_t jobId, void** ppJob);
|
||||
void taosMemPoolCfgUpdate(void* poolHandle, SMemPoolCfg* pCfg);
|
||||
|
||||
#define taosMemPoolFreeClear(ptr) \
|
||||
|
|
|
@ -87,6 +87,8 @@ BoundedQueue* createBoundedQueue(uint32_t maxSize, pq_comp_fn fn, FDelete delete
|
|||
|
||||
void taosBQSetFn(BoundedQueue* q, pq_comp_fn fn);
|
||||
|
||||
void taosBQClear(BoundedQueue* q);
|
||||
|
||||
void destroyBoundedQueue(BoundedQueue* q);
|
||||
|
||||
/*
|
||||
|
|
|
@ -672,7 +672,7 @@ static bool filterWindowWithLimit(SIntervalAggOperatorInfo* pOperatorInfo, STime
|
|||
if (pOperatorInfo->limit == 0) return true;
|
||||
|
||||
if (pOperatorInfo->pBQ == NULL) {
|
||||
pOperatorInfo->pBQ = createBoundedQueue(pOperatorInfo->limit - 1, tsKeyCompFn, NULL, pOperatorInfo);
|
||||
pOperatorInfo->pBQ = createBoundedQueue(pOperatorInfo->limit - 1, tsKeyCompFn, taosAutoMemoryFree, pOperatorInfo);
|
||||
}
|
||||
|
||||
bool shouldFilter = false;
|
||||
|
|
|
@ -44,6 +44,7 @@ extern "C" {
|
|||
#define QW_DEFAULT_RESERVE_MEM_PERCENT 20
|
||||
#define QW_MIN_RESERVE_MEM_SIZE (512 * 1048576UL)
|
||||
#define QW_MIN_MEM_POOL_SIZE (1048576UL)
|
||||
#define QW_MAX_RETIRE_JOB_NUM 10000
|
||||
|
||||
#define QW_DEFAULT_THREAD_TASK_NUM 3
|
||||
|
||||
|
@ -129,6 +130,15 @@ typedef struct SQWTaskStatus {
|
|||
int8_t status;
|
||||
} SQWTaskStatus;
|
||||
|
||||
|
||||
typedef struct SQWJobInfo {
|
||||
int8_t retired;
|
||||
int32_t errCode;
|
||||
SMemPoolJob* memInfo;
|
||||
SHashObj* pSessions;
|
||||
} SQWJobInfo;
|
||||
|
||||
|
||||
typedef struct SQWTaskCtx {
|
||||
SRWLatch lock;
|
||||
int8_t phase;
|
||||
|
@ -166,6 +176,7 @@ typedef struct SQWTaskCtx {
|
|||
SArray *tbInfo; // STbVerInfo
|
||||
|
||||
void *memPoolSession;
|
||||
SQWJobInfo *pJobInfo;
|
||||
} SQWTaskCtx;
|
||||
|
||||
typedef struct SQWSchStatus {
|
||||
|
@ -232,31 +243,15 @@ typedef struct SQWorkerMgmt {
|
|||
int32_t paramIdx;
|
||||
} SQWorkerMgmt;
|
||||
|
||||
typedef struct SQWQueryInfo {
|
||||
int8_t retired;
|
||||
SMemPoolCollection* pCollection;
|
||||
SHashObj* pSessions;
|
||||
} SQWQueryInfo;
|
||||
|
||||
typedef struct SQWRetireLowCtx {
|
||||
int8_t retireBegin;
|
||||
} SQWRetireLowCtx;
|
||||
|
||||
typedef struct SQWRetireMidCtx {
|
||||
int8_t retireBegin;
|
||||
TdThreadCond retired;
|
||||
BoundedQueue* collectionQueue;
|
||||
} SQWRetireMidCtx;
|
||||
|
||||
typedef struct SQWRetireCtx {
|
||||
SQWRetireLowCtx lowCtx;
|
||||
SQWRetireMidCtx midCtx;
|
||||
BoundedQueue* pJobQueue;
|
||||
} SQWRetireCtx;
|
||||
|
||||
typedef struct SQueryMgmt {
|
||||
SRWLatch taskMgmtLock;
|
||||
int32_t concTaskLevel;
|
||||
SHashObj* pQueryInfo;
|
||||
SHashObj* pJobInfo;
|
||||
void* memPoolHandle;
|
||||
SQWRetireCtx retireCtx;
|
||||
} SQueryMgmt;
|
||||
|
@ -482,8 +477,10 @@ void qwDbgSimulateSleep(void);
|
|||
void qwDbgSimulateDead(QW_FPARAMS_DEF, SQWTaskCtx *ctx, bool *rsped);
|
||||
int32_t qwSendExplainResponse(QW_FPARAMS_DEF, SQWTaskCtx *ctx);
|
||||
int32_t qwInitQueryPool(void);
|
||||
void qwDestroyQueryInfo(SQWQueryInfo* pQuery);
|
||||
int32_t qwInitSession(QW_FPARAMS_DEF, void** ppSession);
|
||||
void qwDestroyJobInfo(SQWJobInfo* pJob);
|
||||
void qwRetireJob(SQWJobInfo* pJob);
|
||||
|
||||
int32_t qwInitSession(QW_FPARAMS_DEF, SQWTaskCtx *ctx, void** ppSession);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -15,6 +15,8 @@ int32_t qwGetMemPoolMaxMemSize(int64_t totalSize, int64_t* maxSize) {
|
|||
}
|
||||
|
||||
int32_t qwGetMemPoolChunkSize(int64_t totalSize, int32_t threadNum, int32_t* chunkSize) {
|
||||
//TODO
|
||||
|
||||
*chunkSize = 2 * 1048576;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -53,101 +55,159 @@ void qwIncConcurrentTaskNumCb(void) {
|
|||
//TODO
|
||||
}
|
||||
|
||||
int32_t qwInitQueryInfo(uint64_t qId, SQWQueryInfo* pQuery) {
|
||||
pQuery->pSessions= taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_ENTRY_LOCK);
|
||||
if (NULL == pQuery->pSessions) {
|
||||
qError("fail to init session hash");
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
int32_t qwInitJobInfo(uint64_t qId, SQWJobInfo* pJob) {
|
||||
pJob->pSessions= taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_ENTRY_LOCK);
|
||||
if (NULL == pJob->pSessions) {
|
||||
qError("fail to init session hash, code: 0x%x", terrno);
|
||||
return terrno;
|
||||
}
|
||||
|
||||
int32_t code = taosMemPoolCallocCollection(qId, (void**)&pQuery->pCollection);
|
||||
int32_t code = taosMemPoolCallocJob(qId, (void**)&pJob->memInfo);
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
taosHashCleanup(pQuery->pSessions);
|
||||
taosHashCleanup(pJob->pSessions);
|
||||
pJob->pSessions = NULL;
|
||||
return code;
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t qwInitSession(QW_FPARAMS_DEF, void** ppSession) {
|
||||
int32_t qwInitSession(QW_FPARAMS_DEF, SQWTaskCtx *ctx, void** ppSession) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
SQWQueryInfo* pQuery = NULL;
|
||||
SQWJobInfo* pJob = NULL;
|
||||
|
||||
while (true) {
|
||||
pQuery = (SQWQueryInfo*)taosHashGet(gQueryMgmt.pQueryInfo, &qId, sizeof(qId));
|
||||
if (NULL == pQuery) {
|
||||
SQWQueryInfo queryInfo = {0};
|
||||
code = qwInitQueryInfo(qId, &queryInfo);
|
||||
pJob = (SQWJobInfo*)taosHashAcquire(gQueryMgmt.pJobInfo, &qId, sizeof(qId));
|
||||
if (NULL == pJob) {
|
||||
SQWJobInfo jobInfo = {0};
|
||||
code = qwInitJobInfo(qId, &jobInfo);
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
return code;
|
||||
}
|
||||
|
||||
code = taosHashPut(gQueryMgmt.pQueryInfo, &qId, sizeof(qId), &queryInfo, sizeof(queryInfo));
|
||||
code = taosHashPut(gQueryMgmt.pJobInfo, &qId, sizeof(qId), &jobInfo, sizeof(jobInfo));
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
qwDestroyQueryInfo(&queryInfo);
|
||||
if (-2 == code) {
|
||||
qwDestroyJobInfo(&jobInfo);
|
||||
if (TSDB_CODE_DUP_KEY == code) {
|
||||
code = TSDB_CODE_SUCCESS;
|
||||
continue;
|
||||
}
|
||||
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
return code;
|
||||
}
|
||||
|
||||
pQuery = (SQWQueryInfo*)taosHashGet(gQueryMgmt.pQueryInfo, &qId, sizeof(qId));
|
||||
pJob = (SQWJobInfo*)taosHashAcquire(gQueryMgmt.pJobInfo, &qId, sizeof(qId));
|
||||
if (NULL == pJob) {
|
||||
qError("QID:0x%" PRIx64 " not in joj hash, may be dropped", qId);
|
||||
return TSDB_CODE_QRY_JOB_NOT_EXIST;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
QW_ERR_RET(taosMemPoolInitSession(gQueryMgmt.memPoolHandle, ppSession, pQuery->pCollection));
|
||||
ctx->pJobInfo = pJob;
|
||||
|
||||
QW_ERR_JRET(taosMemPoolInitSession(gQueryMgmt.memPoolHandle, ppSession, pJob->memInfo));
|
||||
|
||||
char id[sizeof(tId) + sizeof(eId)] = {0};
|
||||
QW_SET_TEID(id, tId, eId);
|
||||
|
||||
code = taosHashPut(pQuery->pSessions, id, sizeof(id), ppSession, POINTER_BYTES);
|
||||
code = taosHashPut(pJob->pSessions, id, sizeof(id), ppSession, POINTER_BYTES);
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
qError("fail to put session into query session hash, errno:%d", terrno);
|
||||
return terrno;
|
||||
qError("fail to put session into query session hash, code: 0x%x", code);
|
||||
QW_ERR_JRET(code);
|
||||
}
|
||||
|
||||
_return:
|
||||
|
||||
if (NULL != pJob) {
|
||||
taosHashRelease(gQueryMgmt.pJobInfo, pJob);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
void qwRetireCollectionCb(uint64_t collectionId) {
|
||||
void qwRetireJobCb(SMemPoolJob* mpJob, int32_t errCode) {
|
||||
SQWJobInfo* pJob = (SQWJobInfo*)taosHashGet(gQueryMgmt.pJobInfo, &mpJob->jobId, sizeof(mpJob->jobId));
|
||||
if (NULL == pJob) {
|
||||
qError("QID:0x%" PRIx64 " fail to get job from job hash", mpJob->jobId);
|
||||
return;
|
||||
}
|
||||
|
||||
if (0 == atomic_val_compare_exchange_32(&pJob->errCode, 0, errCode) && 0 == atomic_val_compare_exchange_8(&pJob->retired, 0, 1)) {
|
||||
qwRetireJob(pJob);
|
||||
|
||||
qInfo("QID:0x%" PRIx64 " retired directly, errCode: 0x%x", mpJob->jobId, errCode);
|
||||
} else {
|
||||
qDebug("QID:0x%" PRIx64 " already retired, retired: %d, errCode: 0x%x", mpJob->jobId, atomic_load_8(&pJob->retired), atomic_load_32(&pJob->errCode));
|
||||
}
|
||||
}
|
||||
|
||||
void qwLowLevelRetire(int64_t retireSize) {
|
||||
SQWQueryInfo* pQuery = (SQWQueryInfo*)taosHashIterate(gQueryMgmt.pQueryInfo, NULL);
|
||||
while (pQuery) {
|
||||
int64_t aSize = atomic_load_64(&pQuery->pCollection->allocMemSize);
|
||||
if (aSize >= retireSize) {
|
||||
atomic_store_8(&pQuery->retired, 1);
|
||||
|
||||
//TODO RETIRE JOB/TASKS DIRECTLY
|
||||
void qwLowLevelRetire(int64_t retireSize, int32_t errCode) {
|
||||
SQWJobInfo* pJob = (SQWJobInfo*)taosHashIterate(gQueryMgmt.pJobInfo, NULL);
|
||||
while (pJob) {
|
||||
int64_t aSize = atomic_load_64(&pJob->memInfo->allocMemSize);
|
||||
if (aSize >= retireSize && 0 == atomic_val_compare_exchange_32(&pJob->errCode, 0, errCode) && 0 == atomic_val_compare_exchange_8(&pJob->retired, 0, 1)) {
|
||||
qwRetireJob(pJob);
|
||||
|
||||
qDebug("QID:0x%" PRIx64 " job retired cause of low level memory retire, usedSize:%" PRId64 ", retireSize:%" PRId64,
|
||||
pQuery->pCollection->collectionId, aSize, retireSize);
|
||||
pJob->memInfo->jobId, aSize, retireSize);
|
||||
|
||||
taosHashCancelIterate(gQueryMgmt.pQueryInfo, pQuery);
|
||||
taosHashCancelIterate(gQueryMgmt.pJobInfo, pJob);
|
||||
break;
|
||||
}
|
||||
|
||||
pQuery = (SQWQueryInfo*)taosHashIterate(gQueryMgmt.pQueryInfo, pQuery);
|
||||
pJob = (SQWJobInfo*)taosHashIterate(gQueryMgmt.pJobInfo, pJob);
|
||||
}
|
||||
}
|
||||
|
||||
void qwMidLevelRetire(int64_t retireSize) {
|
||||
void qwMidLevelRetire(int64_t retireSize, int32_t errCode) {
|
||||
SQWJobInfo* pJob = (SQWJobInfo*)taosHashIterate(gQueryMgmt.pJobInfo, NULL);
|
||||
PriorityQueueNode qNode;
|
||||
while (NULL != pJob) {
|
||||
if (0 == atomic_load_8(&pJob->retired)) {
|
||||
qNode.data = pJob;
|
||||
(void)taosBQPush(gQueryMgmt.retireCtx.pJobQueue, &qNode);
|
||||
}
|
||||
|
||||
pJob = (SQWJobInfo*)taosHashIterate(gQueryMgmt.pJobInfo, pJob);
|
||||
}
|
||||
|
||||
PriorityQueueNode* pNode = NULL;
|
||||
int64_t retiredSize = 0;
|
||||
while (retiredSize < retireSize) {
|
||||
pNode = taosBQTop(gQueryMgmt.retireCtx.pJobQueue);
|
||||
if (NULL == pNode) {
|
||||
break;
|
||||
}
|
||||
|
||||
pJob = (SQWJobInfo*)pNode->data;
|
||||
if (atomic_load_8(&pJob->retired)) {
|
||||
taosBQPop(gQueryMgmt.retireCtx.pJobQueue);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (0 == atomic_val_compare_exchange_32(&pJob->errCode, 0, errCode) && 0 == atomic_val_compare_exchange_8(&pJob->retired, 0, 1)) {
|
||||
int64_t aSize = atomic_load_64(&pJob->memInfo->allocMemSize);
|
||||
|
||||
qwRetireJob(pJob);
|
||||
|
||||
qDebug("QID:0x%" PRIx64 " job retired cause of mid level memory retire, usedSize:%" PRId64 ", retireSize:%" PRId64,
|
||||
pJob->memInfo->jobId, aSize, retireSize);
|
||||
|
||||
retiredSize += aSize;
|
||||
}
|
||||
|
||||
taosBQPop(gQueryMgmt.retireCtx.pJobQueue);
|
||||
}
|
||||
|
||||
taosBQClear(gQueryMgmt.retireCtx.pJobQueue);
|
||||
}
|
||||
|
||||
|
||||
void qwRetireCollectionsCb(int64_t retireSize, bool lowLevelRetire) {
|
||||
if (lowLevelRetire) {
|
||||
qwLowLevelRetire(retireSize);
|
||||
} else {
|
||||
qwMidLevelRetire(retireSize);
|
||||
}
|
||||
void qwRetireJobsCb(int64_t retireSize, bool lowLevelRetire, int32_t errCode) {
|
||||
(lowLevelRetire) ? qwLowLevelRetire(retireSize, errCode) : qwMidLevelRetire(retireSize, errCode);
|
||||
}
|
||||
|
||||
int32_t qwGetQueryMemPoolMaxSize(int64_t* pMaxSize, bool* autoMaxSize) {
|
||||
|
@ -161,8 +221,8 @@ int32_t qwGetQueryMemPoolMaxSize(int64_t* pMaxSize, bool* autoMaxSize) {
|
|||
int64_t memSize = 0;
|
||||
int32_t code = taosGetSysAvailMemory(&memSize);
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
qError("get system avaiable memory size failed, errno: %d", errno);
|
||||
return TAOS_SYSTEM_ERROR(errno);
|
||||
qError("get system avaiable memory size failed, error: 0x%x", code);
|
||||
return code;
|
||||
}
|
||||
|
||||
code = qwGetMemPoolMaxMemSize(memSize, pMaxSize);
|
||||
|
@ -177,9 +237,9 @@ int32_t qwGetQueryMemPoolMaxSize(int64_t* pMaxSize, bool* autoMaxSize) {
|
|||
|
||||
void qwCheckUpateCfgCb(void* pHandle, void* cfg) {
|
||||
SMemPoolCfg* pCfg = (SMemPoolCfg*)cfg;
|
||||
int64_t newCollectionQuota = tsSingleQueryMaxMemorySize * 1048576UL;
|
||||
if (pCfg->collectionQuota != newCollectionQuota) {
|
||||
atomic_store_64(&pCfg->collectionQuota, newCollectionQuota);
|
||||
int64_t newJobQuota = tsSingleQueryMaxMemorySize * 1048576UL;
|
||||
if (pCfg->jobQuota != newJobQuota) {
|
||||
atomic_store_64(&pCfg->jobQuota, newJobQuota);
|
||||
}
|
||||
|
||||
int64_t maxSize = 0;
|
||||
|
@ -198,13 +258,28 @@ void qwCheckUpateCfgCb(void* pHandle, void* cfg) {
|
|||
}
|
||||
}
|
||||
|
||||
static bool qwJobMemSizeCompFn(void* l, void* r, void* param) {
|
||||
SQWJobInfo* left = (SQWJobInfo*)l;
|
||||
SQWJobInfo* right = (SQWJobInfo*)r;
|
||||
if (atomic_load_8(&right->retired)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return atomic_load_64(&right->memInfo->allocMemSize) < atomic_load_64(&left->memInfo->allocMemSize);
|
||||
}
|
||||
|
||||
|
||||
int32_t qwInitQueryPool(void) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
|
||||
|
||||
#ifdef LINUX
|
||||
if (!tsQueryUseMemoryPool) {
|
||||
qDebug("query memory pool disabled");
|
||||
#endif
|
||||
qInfo("query memory pool disabled");
|
||||
return code;
|
||||
#ifdef LINUX
|
||||
}
|
||||
#endif
|
||||
|
||||
SMemPoolCfg cfg = {0};
|
||||
int64_t maxSize = 0;
|
||||
|
@ -216,12 +291,12 @@ int32_t qwInitQueryPool(void) {
|
|||
|
||||
cfg.threadNum = 10; //TODO
|
||||
cfg.evicPolicy = E_EVICT_AUTO; //TODO
|
||||
cfg.collectionQuota = tsSingleQueryMaxMemorySize * 1048576UL;
|
||||
cfg.jobQuota = tsSingleQueryMaxMemorySize * 1048576UL;
|
||||
cfg.cb.setSessFp = qwSetConcurrentTaskNumCb;
|
||||
cfg.cb.decSessFp = qwDecConcurrentTaskNumCb;
|
||||
cfg.cb.incSessFp = qwIncConcurrentTaskNumCb;
|
||||
cfg.cb.retiresFp = qwRetireCollectionsCb;
|
||||
cfg.cb.retireFp = qwRetireCollectionCb;
|
||||
cfg.cb.retireJobsFp = qwRetireJobsCb;
|
||||
cfg.cb.retireJobFp = qwRetireJobCb;
|
||||
cfg.cb.cfgUpdateFp = qwCheckUpateCfgCb;
|
||||
|
||||
code = qwGetMemPoolChunkSize(cfg.maxSize, cfg.threadNum, &cfg.chunkSize);
|
||||
|
@ -229,18 +304,24 @@ int32_t qwInitQueryPool(void) {
|
|||
return code;
|
||||
}
|
||||
|
||||
gQueryMgmt.pJobInfo = taosHashInit(1024, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_ENTRY_LOCK);
|
||||
if (NULL == gQueryMgmt.pJobInfo) {
|
||||
qError("init job hash failed, error:0x%x", terrno);
|
||||
return terrno;
|
||||
}
|
||||
|
||||
gQueryMgmt.retireCtx.pJobQueue = createBoundedQueue(QW_MAX_RETIRE_JOB_NUM, qwJobMemSizeCompFn, NULL, NULL);
|
||||
if (NULL == gQueryMgmt.retireCtx.pJobQueue) {
|
||||
qError("init job bounded queue failed, error:0x%x", terrno);
|
||||
return terrno;
|
||||
}
|
||||
|
||||
code = taosMemPoolOpen(QW_QUERY_MEM_POOL_NAME, &cfg, &gQueryMgmt.memPoolHandle);
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
return code;
|
||||
}
|
||||
|
||||
gQueryMgmt.pQueryInfo = taosHashInit(1024, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_ENTRY_LOCK);
|
||||
if (NULL == gQueryMgmt.pQueryInfo) {
|
||||
qError("init query hash failed");
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
qDebug("query memory pool initialized");
|
||||
qInfo("query memory pool initialized");
|
||||
|
||||
return code;
|
||||
}
|
||||
|
|
|
@ -711,7 +711,11 @@ void qwClearExpiredSch(SQWorker *mgmt, SArray *pExpiredSch) {
|
|||
}
|
||||
}
|
||||
|
||||
void qwDestroyQueryInfo(SQWQueryInfo* pQuery) {
|
||||
void qwDestroyJobInfo(SQWJobInfo* pJob) {
|
||||
//TODO
|
||||
}
|
||||
|
||||
void qwRetireJob(SQWJobInfo* pJob) {
|
||||
//TODO
|
||||
}
|
||||
|
||||
|
|
|
@ -759,7 +759,7 @@ int32_t qwPreprocessQuery(QW_FPARAMS_DEF, SQWMsg *qwMsg) {
|
|||
ctx->phase = -1;
|
||||
|
||||
if (NULL != gQueryMgmt.memPoolHandle) {
|
||||
QW_ERR_JRET(qwInitSession(QW_FPARAMS(), &ctx->memPoolSession));
|
||||
QW_ERR_JRET(qwInitSession(QW_FPARAMS(), ctx, &ctx->memPoolSession));
|
||||
}
|
||||
|
||||
QW_ERR_JRET(qwAddTaskStatus(QW_FPARAMS(), JOB_TASK_STATUS_INIT));
|
||||
|
|
|
@ -193,26 +193,15 @@ typedef struct SMPStatInfo {
|
|||
} SMPStatInfo;
|
||||
|
||||
|
||||
typedef struct SMPCollection {
|
||||
SMemPoolCollection collection; // KEEP IT FIRST
|
||||
typedef struct SMPJob {
|
||||
SMemPoolJob job; // KEEP IT FIRST
|
||||
int32_t remainSession;
|
||||
SMPStatInfo stat;
|
||||
} SMPCollection;
|
||||
|
||||
|
||||
typedef struct SMPSession {
|
||||
SMPListNode list;
|
||||
|
||||
int64_t sessionId;
|
||||
|
||||
void* pCollection;
|
||||
SMPCollection* pMpCollection;
|
||||
bool needRetire;
|
||||
SMPCtrlInfo ctrlInfo;
|
||||
} SMPJob;
|
||||
|
||||
typedef struct SMPSessionChunk {
|
||||
int64_t allocChunkNum;
|
||||
int64_t allocChunkMemSize;
|
||||
int64_t allocMemSize;
|
||||
int64_t maxAllocMemSize;
|
||||
int64_t reUseChunkNum;
|
||||
|
||||
int32_t srcChunkNum;
|
||||
|
@ -231,6 +220,18 @@ typedef struct SMPSession {
|
|||
|
||||
SMPNSChunk *reUseNSChunkHead;
|
||||
SMPNSChunk *reUseNSChunkTail;
|
||||
} SMPSessionChunk;
|
||||
|
||||
typedef struct SMPSession {
|
||||
SMPListNode list;
|
||||
|
||||
int64_t sessionId;
|
||||
SMPJob* pJob;
|
||||
SMPCtrlInfo ctrlInfo;
|
||||
int64_t allocMemSize;
|
||||
int64_t maxAllocMemSize;
|
||||
|
||||
SMPSessionChunk chunk;
|
||||
|
||||
SMPStatInfo stat;
|
||||
} SMPSession;
|
||||
|
@ -240,32 +241,20 @@ typedef struct SMPCacheGroupInfo {
|
|||
int64_t allocNum;
|
||||
int32_t groupNum;
|
||||
SMPCacheGroup *pGrpHead;
|
||||
SMPCacheGroup *pGrpTail;
|
||||
void *pIdleList;
|
||||
} SMPCacheGroupInfo;
|
||||
|
||||
|
||||
typedef struct SMemPool {
|
||||
char *name;
|
||||
int16_t slotId;
|
||||
SMemPoolCfg cfg;
|
||||
int64_t memRetireThreshold[3];
|
||||
int64_t memRetireUnit;
|
||||
typedef struct SMPChunkMgmt {
|
||||
int32_t maxChunkNum;
|
||||
SMPCtrlInfo ctrlInfo;
|
||||
|
||||
int16_t maxDiscardSize;
|
||||
double threadChunkReserveNum;
|
||||
int64_t allocChunkNum;
|
||||
int64_t allocChunkSize;
|
||||
int64_t allocNSChunkNum;
|
||||
int64_t allocNSChunkSize;
|
||||
int64_t allocMemSize;
|
||||
int64_t maxAllocMemSize;
|
||||
|
||||
SMPCacheGroupInfo chunkCache;
|
||||
SMPCacheGroupInfo NSChunkCache;
|
||||
SMPCacheGroupInfo sessionCache;
|
||||
|
||||
int32_t readyChunkNum;
|
||||
int32_t readyChunkReserveNum;
|
||||
|
@ -275,11 +264,28 @@ typedef struct SMemPool {
|
|||
SMPChunk *readyChunkHead;
|
||||
SMPChunk *readyChunkTail;
|
||||
|
||||
int64_t readyNSChunkNum;
|
||||
SMPChunk *readyNSChunkHead;
|
||||
SMPChunk *readyNSChunkTail;
|
||||
int64_t readyNSChunkNum;
|
||||
SMPChunk *readyNSChunkHead;
|
||||
SMPChunk *readyNSChunkTail;
|
||||
} SMPChunkMgmt;
|
||||
|
||||
SMPStatInfo stat;
|
||||
|
||||
typedef struct SMemPool {
|
||||
char *name;
|
||||
int16_t slotId;
|
||||
SMemPoolCfg cfg;
|
||||
int64_t retireThreshold[3];
|
||||
int64_t retireUnit;
|
||||
SMPCtrlInfo ctrlInfo;
|
||||
|
||||
int64_t maxAllocMemSize;
|
||||
int64_t allocMemSize;
|
||||
|
||||
SMPCacheGroupInfo sessionCache;
|
||||
|
||||
SMPChunkMgmt chunk;
|
||||
|
||||
SMPStatInfo stat;
|
||||
} SMemPool;
|
||||
|
||||
typedef enum EMPMemStrategy {
|
||||
|
@ -305,6 +311,24 @@ typedef struct SMemPoolMgmt {
|
|||
int32_t code;
|
||||
} SMemPoolMgmt;
|
||||
|
||||
typedef int32_t (*mpAllocFunc)(SMemPool*, SMPSession*, int64_t, uint32_t, void**);
|
||||
typedef void (*mpFreeFunc)(SMemPool*, SMPSession*, void *, int64_t*);
|
||||
typedef int64_t (*mpGetSizeFunc)(SMemPool*, SMPSession*, void*);
|
||||
typedef int32_t (*mpReallocFunc)(SMemPool*, SMPSession*, void **, int64_t, int64_t*);
|
||||
typedef int32_t (*mpInitSessionFunc)(SMemPool*, SMPSession*);
|
||||
typedef int32_t (*mpInitFunc)(SMemPool*, char*, SMemPoolCfg*);
|
||||
typedef int32_t (*mpUpdateCfgFunc)(SMemPool*);
|
||||
|
||||
typedef struct SMPStrategyFp {
|
||||
mpInitFunc initFp;
|
||||
mpAllocFunc allocFp;
|
||||
mpFreeFunc freeFp;
|
||||
mpGetSizeFunc getSizeFp;
|
||||
mpReallocFunc reallocFp;
|
||||
mpInitSessionFunc initSessionFp;
|
||||
mpUpdateCfgFunc updateCfgFp;
|
||||
} SMPStrategyFp;
|
||||
|
||||
#define MP_GET_FLAG(st, f) ((st) & (f))
|
||||
#define MP_SET_FLAG(st, f) (st) |= (f)
|
||||
#define MP_CLR_FLAG(st, f) (st) &= (~f)
|
||||
|
@ -403,6 +427,28 @@ enum {
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
// direct
|
||||
int32_t mpDirectAlloc(SMemPool* pPool, SMPSession* pSession, int64_t size, uint32_t alignment, void** ppRes);
|
||||
int64_t mpDirectGetMemSize(SMemPool* pPool, SMPSession* pSession, void *ptr);
|
||||
void mpDirectFree(SMemPool* pPool, SMPSession* pSession, void *ptr, int64_t* origSize);
|
||||
int32_t mpDirectRealloc(SMemPool* pPool, SMPSession* pSession, void **pPtr, int64_t size, int64_t* origSize);
|
||||
|
||||
// chunk
|
||||
int32_t mpChunkInit(SMemPool* pPool, char* poolName, SMemPoolCfg* cfg);
|
||||
int64_t mpChunkGetMemSize(SMemPool* pPool, SMPSession* pSession, void *ptr);
|
||||
int32_t mpChunkAlloc(SMemPool* pPool, SMPSession* pSession, int64_t size, uint32_t alignment, void** ppRes);
|
||||
void mpChunkFree(SMemPool* pPool, SMPSession* pSession, void *ptr, int64_t* origSize);
|
||||
int32_t mpChunkRealloc(SMemPool* pPool, SMPSession* pSession, void **pPtr, int64_t size, int64_t* origSize);
|
||||
int32_t mpChunkInitSession(SMemPool* pPool, SMPSession* pSession);
|
||||
int32_t mpChunkUpdateCfg(SMemPool* pPool);
|
||||
|
||||
|
||||
int32_t mpPopIdleNode(SMemPool* pPool, SMPCacheGroupInfo* pInfo, void** ppRes);
|
||||
int32_t mpChkQuotaOverflow(SMemPool* pPool, SMPSession* pSession, int64_t size);
|
||||
void mpUpdateAllocSize(SMemPool* pPool, SMPSession* pSession, int64_t size);
|
||||
int32_t mpAddCacheGroup(SMemPool* pPool, SMPCacheGroupInfo* pInfo, SMPCacheGroup* pHead);
|
||||
int32_t mpMalloc(SMemPool* pPool, SMPSession* pSession, int64_t size, uint32_t alignment, void** ppRes);
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -0,0 +1,317 @@
|
|||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "osMemPool.h"
|
||||
#include "tmempoolInt.h"
|
||||
#include "tlog.h"
|
||||
#include "tutil.h"
|
||||
|
||||
|
||||
int32_t mpChunkNew(SMemPool* pPool, SMPChunk** ppChunk) {
|
||||
SMPChunk* pChunk = NULL;
|
||||
MP_ERR_RET(mpPopIdleNode(pPool, &pPool->chunk.chunkCache, (void**)&pChunk));
|
||||
|
||||
pChunk->pMemStart = taosMemMalloc(pPool->cfg.chunkSize);
|
||||
if (NULL == pChunk->pMemStart) {
|
||||
uError("add new chunk, memory malloc %d failed, code: 0x%x", pPool->cfg.chunkSize, terrno);
|
||||
return terrno;
|
||||
}
|
||||
|
||||
pPool->chunk.allocChunkNum++;
|
||||
pPool->chunk.allocChunkSize += pPool->cfg.chunkSize;
|
||||
|
||||
*ppChunk = pChunk;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int32_t mpChunkNewNS(SMemPool* pPool, SMPNSChunk** ppChunk, int64_t chunkSize) {
|
||||
SMPNSChunk* pChunk = NULL;
|
||||
MP_ERR_RET(mpPopIdleNode(pPool, &pPool->chunk.NSChunkCache, (void**)&pChunk));
|
||||
|
||||
pChunk->pMemStart = taosMemMalloc(chunkSize);
|
||||
if (NULL == pChunk->pMemStart) {
|
||||
uError("add new NS chunk, memory malloc %" PRId64 " failed, code: 0x%x", chunkSize, terrno);
|
||||
return terrno;
|
||||
}
|
||||
|
||||
pChunk->memBytes = chunkSize;
|
||||
MP_SET_FLAG(pChunk->flags, MP_CHUNK_FLAG_NS_CHUNK);
|
||||
|
||||
pPool->chunk.allocNSChunkNum++;
|
||||
pPool->chunk.allocNSChunkSize += pPool->cfg.chunkSize;
|
||||
|
||||
*ppChunk = pChunk;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int32_t mpChunkPrepare(SMemPool* pPool, int32_t num) {
|
||||
SMPChunk* pChunk = NULL;
|
||||
for (int32_t i = 0; i < num; ++i) {
|
||||
MP_ERR_RET(mpChunkNew(pPool, &pChunk));
|
||||
|
||||
pPool->chunk.readyChunkTail->list.pNext = pChunk;
|
||||
pPool->chunk.readyChunkTail = pChunk;
|
||||
|
||||
atomic_add_fetch_32(&pPool->chunk.readyChunkNum, 1);
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int32_t mpChunkEnsureCapacity(SMemPool* pPool, SMPChunkMgmt* pChunk) {
|
||||
if (E_EVICT_ALL == pPool->cfg.evicPolicy) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t readyMissNum = pChunk->readyChunkReserveNum - atomic_load_32(&pChunk->readyChunkNum);
|
||||
if (readyMissNum <= 0) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
MP_ERR_RET(mpChunkPrepare(pPool, readyMissNum));
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
void mpChunkNotifyLowNum(SMemPool* pPool) {
|
||||
|
||||
}
|
||||
|
||||
int32_t mpChunkRetrieve(SMemPool* pPool, SMPChunk** ppChunk) {
|
||||
SMPCacheGroup* pCache = NULL;
|
||||
SMPChunk* pChunk = NULL;
|
||||
int32_t readyChunkNum = atomic_sub_fetch_32(&pPool->chunk.readyChunkNum, 1);
|
||||
if (readyChunkNum >= 0) {
|
||||
if (atomic_add_fetch_32(&pPool->chunk.readyChunkGotNum, 1) == pPool->chunk.readyChunkLowNum) {
|
||||
mpChunkNotifyLowNum(pPool);
|
||||
}
|
||||
|
||||
pChunk = (SMPChunk*)atomic_load_ptr(&pPool->chunk.readyChunkHead->list.pNext);
|
||||
while (atomic_val_compare_exchange_ptr(&pPool->chunk.readyChunkHead->list.pNext, pChunk, pChunk->list.pNext) != pChunk) {
|
||||
pChunk = (SMPChunk*)atomic_load_ptr(&pPool->chunk.readyChunkHead->list.pNext);
|
||||
}
|
||||
|
||||
*ppChunk = pChunk;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
} else {
|
||||
atomic_add_fetch_32(&pPool->chunk.readyChunkNum, 1);
|
||||
}
|
||||
|
||||
MP_RET(mpChunkNew(pPool, ppChunk));
|
||||
}
|
||||
|
||||
int32_t mpChunkRetrieveFromSession(SMemPool* pPool, SMPSession* pSession, int64_t size, SMPChunk** ppChunk, SMPChunk** ppPreChunk) {
|
||||
SMPChunk* pChunk = pSession->chunk.srcChunkHead;
|
||||
while (NULL != pChunk) {
|
||||
if ((pChunk->offset + size) <= pPool->cfg.chunkSize) {
|
||||
*ppChunk = pChunk;
|
||||
break;
|
||||
}
|
||||
|
||||
*ppPreChunk = pChunk;
|
||||
pChunk = (SMPChunk*)pChunk->list.pNext;
|
||||
}
|
||||
|
||||
if (NULL == *ppChunk) {
|
||||
*ppPreChunk = NULL;
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t mpChunkAllocMem(SMemPool* pPool, SMPSession* pSession, int64_t size, uint32_t alignment, void** ppRes) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
SMPChunk* pChunk = NULL, *preSrcChunk = NULL;
|
||||
void* pRes = NULL;
|
||||
int64_t totalSize = size + sizeof(SMPMemHeader) + sizeof(SMPMemTailer);
|
||||
|
||||
if (pSession->chunk.srcChunkNum > 0) {
|
||||
MP_ERR_JRET(mpChunkRetrieveFromSession(pPool, pSession, totalSize, &pChunk, &preSrcChunk));
|
||||
}
|
||||
|
||||
if (NULL == pChunk) {
|
||||
MP_ERR_JRET(mpChunkNew(pPool, &pChunk));
|
||||
|
||||
pSession->chunk.allocChunkNum++;
|
||||
pSession->chunk.allocChunkMemSize += pPool->cfg.chunkSize;
|
||||
mpUpdateAllocSize(pPool, pSession, totalSize);
|
||||
|
||||
MP_ADD_TO_CHUNK_LIST(pSession->chunk.srcChunkHead, pSession->chunk.srcChunkTail, pSession->chunk.srcChunkNum, pChunk);
|
||||
MP_ADD_TO_CHUNK_LIST(pSession->chunk.inUseChunkHead, pSession->chunk.inUseChunkTail, pSession->chunk.inUseChunkNum, pChunk);
|
||||
}
|
||||
|
||||
SMPMemHeader* pHeader = (SMPMemHeader*)(pChunk->pMemStart + pChunk->offset);
|
||||
MP_INIT_MEM_HEADER(pHeader, size, false);
|
||||
|
||||
pRes = (void*)(pHeader + 1);
|
||||
pChunk->offset += totalSize;
|
||||
|
||||
if (pChunk->offset >= (pPool->cfg.chunkSize - pPool->chunk.maxDiscardSize)) {
|
||||
if (NULL == preSrcChunk) {
|
||||
pSession->chunk.srcChunkHead = NULL;
|
||||
pSession->chunk.srcChunkTail = NULL;
|
||||
} else {
|
||||
preSrcChunk->list.pNext = pChunk->list.pNext;
|
||||
}
|
||||
|
||||
pSession->chunk.srcChunkNum--;
|
||||
}
|
||||
|
||||
|
||||
_return:
|
||||
|
||||
*ppRes = pRes;
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t mpChunkNSAllocMem(SMemPool* pPool, SMPSession* pSession, int64_t size, uint32_t alignment, void** ppRes) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
SMPNSChunk* pChunk = NULL;
|
||||
void* pRes = NULL;
|
||||
int64_t totalSize = size + sizeof(SMPMemHeader) + sizeof(SMPMemTailer) + alignment;
|
||||
|
||||
MP_ERR_JRET(mpChunkNewNS(pPool, &pChunk, totalSize));
|
||||
SMPMemHeader* pHeader = (SMPMemHeader*)pChunk->pMemStart;
|
||||
MP_INIT_MEM_HEADER(pHeader, size, false);
|
||||
|
||||
pRes = (void*)(pHeader + 1);
|
||||
|
||||
pSession->chunk.allocChunkNum++;
|
||||
pSession->chunk.allocChunkMemSize += totalSize;
|
||||
mpUpdateAllocSize(pPool, pSession, totalSize);
|
||||
|
||||
if (NULL == pSession->chunk.inUseNSChunkHead) {
|
||||
pSession->chunk.inUseNSChunkHead = pChunk;
|
||||
pSession->chunk.inUseNSChunkTail = pChunk;
|
||||
} else {
|
||||
pSession->chunk.inUseNSChunkTail->list.pNext = pChunk;
|
||||
}
|
||||
|
||||
_return:
|
||||
|
||||
*ppRes = pRes;
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
int32_t mpChunkInit(SMemPool* pPool, char* poolName, SMemPoolCfg* cfg) {
|
||||
SMPChunkMgmt* pChunk = &pPool->chunk;
|
||||
pChunk->threadChunkReserveNum = 1;
|
||||
|
||||
pChunk->chunkCache.nodeSize = sizeof(SMPChunk);
|
||||
pChunk->NSChunkCache.groupNum = MP_NSCHUNK_CACHE_ALLOC_BATCH_SIZE;
|
||||
pChunk->NSChunkCache.nodeSize = sizeof(SMPNSChunk);
|
||||
|
||||
MP_ERR_RET(mpAddCacheGroup(pPool, &pChunk->chunkCache, NULL));
|
||||
MP_ERR_RET(mpAddCacheGroup(pPool, &pChunk->NSChunkCache, NULL));
|
||||
|
||||
MP_ERR_RET(mpPopIdleNode(pPool, &pChunk->chunkCache, (void**)&pChunk->readyChunkHead));
|
||||
pChunk->readyChunkTail = pChunk->readyChunkHead;
|
||||
|
||||
MP_ERR_RET(mpChunkEnsureCapacity(pPool, pChunk));
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int64_t mpChunkGetMemSize(SMemPool* pPool, SMPSession* pSession, void *ptr) {
|
||||
SMPMemHeader* pHeader = (SMPMemHeader*)ptr - 1;
|
||||
return pHeader->size;
|
||||
}
|
||||
|
||||
int32_t mpChunkAlloc(SMemPool* pPool, SMPSession* pSession, int64_t size, uint32_t alignment, void** ppRes) {
|
||||
MP_RET((size > pPool->cfg.chunkSize) ? mpChunkNSAllocMem(pPool, pSession, size, alignment, ppRes) : mpChunkAllocMem(pPool, pSession, size, alignment, ppRes));
|
||||
}
|
||||
|
||||
|
||||
void mpChunkFree(SMemPool* pPool, SMPSession* pSession, void *ptr, int64_t* origSize) {
|
||||
int64_t oSize = mpChunkGetMemSize(pPool, pSession, ptr);
|
||||
if (origSize) {
|
||||
*origSize = oSize;
|
||||
}
|
||||
|
||||
// TODO
|
||||
|
||||
atomic_sub_fetch_64(&pSession->allocMemSize, oSize);
|
||||
atomic_sub_fetch_64(&pPool->allocMemSize, oSize);
|
||||
}
|
||||
|
||||
|
||||
int32_t mpChunkRealloc(SMemPool* pPool, SMPSession* pSession, void **pPtr, int64_t size, int64_t* origSize) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
|
||||
if (*origSize >= size) {
|
||||
SMPMemHeader* pHeader = (SMPMemHeader*)((char*)*pPtr - sizeof(SMPMemHeader));
|
||||
pHeader->size = size;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
void* res = NULL;
|
||||
MP_ERR_JRET(mpMalloc(pPool, pSession, size, 0, &res));
|
||||
SMPMemHeader* pOrigHeader = (SMPMemHeader*)((char*)*pPtr - sizeof(SMPMemHeader));
|
||||
SMPMemHeader* pNewHeader = (SMPMemHeader*)((char*)res - sizeof(SMPMemHeader));
|
||||
|
||||
TAOS_MEMCPY(res, *pPtr, *origSize);
|
||||
mpChunkFree(pPool, pSession, *pPtr, NULL);
|
||||
*pPtr = res;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
||||
_return:
|
||||
|
||||
mpChunkFree(pPool, pSession, *pPtr, NULL);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t mpChunkInitSession(SMemPool* pPool, SMPSession* pSession) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
SMPChunk* pChunk = NULL;
|
||||
|
||||
MP_ERR_RET(mpChunkRetrieve(pPool, &pChunk));
|
||||
|
||||
pSession->chunk.allocChunkNum = 1;
|
||||
pSession->chunk.allocChunkMemSize = pPool->cfg.chunkSize;
|
||||
|
||||
MP_ADD_TO_CHUNK_LIST(pSession->chunk.srcChunkHead, pSession->chunk.srcChunkTail, pSession->chunk.srcChunkNum, pChunk);
|
||||
MP_ADD_TO_CHUNK_LIST(pSession->chunk.inUseChunkHead, pSession->chunk.inUseChunkTail, pSession->chunk.inUseChunkNum, pChunk);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t mpChunkUpdateCfg(SMemPool* pPool) {
|
||||
pPool->chunk.maxChunkNum = pPool->cfg.maxSize / pPool->cfg.chunkSize;
|
||||
if (pPool->chunk.maxChunkNum <= 0) {
|
||||
uError("invalid memory pool max chunk num, maxSize:%" PRId64 ", chunkSize:%d", pPool->cfg.maxSize, pPool->cfg.chunkSize);
|
||||
return TSDB_CODE_INVALID_MEM_POOL_PARAM;
|
||||
}
|
||||
|
||||
pPool->chunk.readyChunkReserveNum = TMIN(pPool->cfg.threadNum * pPool->chunk.threadChunkReserveNum, pPool->chunk.maxChunkNum);
|
||||
|
||||
pPool->chunk.chunkCache.groupNum = TMAX(pPool->chunk.maxChunkNum / 10, MP_CHUNK_CACHE_ALLOC_BATCH_SIZE);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "osMemPool.h"
|
||||
#include "tmempoolInt.h"
|
||||
#include "tlog.h"
|
||||
#include "tutil.h"
|
||||
|
||||
int32_t mpDirectAlloc(SMemPool* pPool, SMPSession* pSession, int64_t size, uint32_t alignment, void** ppRes) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
MP_ERR_RET(mpChkQuotaOverflow(pPool, pSession, size));
|
||||
|
||||
void* res = alignment ? taosMemMallocAlign(alignment, size) : taosMemMalloc(size);
|
||||
if (NULL != res) {
|
||||
mpUpdateAllocSize(pPool, pSession, size);
|
||||
} else {
|
||||
(void)atomic_sub_fetch_64(&pSession->pJob->job.allocMemSize, size);
|
||||
(void)atomic_sub_fetch_64(&pPool->allocMemSize, size);
|
||||
|
||||
uError("malloc %" PRId64 " alignment %d failed, code: 0x%x", size, alignment, terrno);
|
||||
|
||||
code = terrno;
|
||||
}
|
||||
|
||||
*ppRes = res;
|
||||
|
||||
MP_RET(code);
|
||||
}
|
||||
|
||||
int64_t mpDirectGetMemSize(SMemPool* pPool, SMPSession* pSession, void *ptr) {
|
||||
return taosMemSize(ptr);
|
||||
}
|
||||
|
||||
void mpDirectFree(SMemPool* pPool, SMPSession* pSession, void *ptr, int64_t* origSize) {
|
||||
int64_t oSize = taosMemSize(ptr);
|
||||
if (origSize) {
|
||||
*origSize = oSize;
|
||||
}
|
||||
taosMemFree(ptr);
|
||||
|
||||
(void)atomic_sub_fetch_64(&pSession->allocMemSize, oSize);
|
||||
(void)atomic_sub_fetch_64(&pSession->pJob->job.allocMemSize, oSize);
|
||||
(void)atomic_sub_fetch_64(&pPool->allocMemSize, oSize);
|
||||
}
|
||||
|
||||
int32_t mpDirectRealloc(SMemPool* pPool, SMPSession* pSession, void **pPtr, int64_t size, int64_t* origSize) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
|
||||
MP_ERR_RET(mpChkQuotaOverflow(pPool, pSession, size));
|
||||
|
||||
*pPtr = taosMemRealloc(*pPtr, size);
|
||||
if (NULL != *pPtr) {
|
||||
mpUpdateAllocSize(pPool, pSession, size - *origSize);
|
||||
} else {
|
||||
MP_ERR_RET(terrno);
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
@ -343,6 +343,13 @@ BoundedQueue* createBoundedQueue(uint32_t maxSize, pq_comp_fn fn, FDelete delete
|
|||
|
||||
void taosBQSetFn(BoundedQueue* q, pq_comp_fn fn) { taosPQSetFn(q->queue, fn); }
|
||||
|
||||
void taosBQClear(BoundedQueue* q) {
|
||||
if (q->queue->deleteFn)
|
||||
taosArrayClearEx(q->queue->container, q->queue->deleteFn);
|
||||
else
|
||||
taosArrayClear(q->queue->container);
|
||||
}
|
||||
|
||||
void destroyBoundedQueue(BoundedQueue* q) {
|
||||
if (!q) return;
|
||||
destroyPriorityQueue(q->queue);
|
||||
|
@ -357,11 +364,9 @@ PriorityQueueNode* taosBQPush(BoundedQueue* q, PriorityQueueNode* n) {
|
|||
} else {
|
||||
void* p = top->data;
|
||||
top->data = n->data;
|
||||
n->data = p;
|
||||
if (q->queue->deleteFn) {
|
||||
n->data = p;
|
||||
q->queue->deleteFn(n->data);
|
||||
} else {
|
||||
taosMemoryFree(n->data);
|
||||
}
|
||||
}
|
||||
return pqHeapify(q->queue, 0, taosBQSize(q));
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue