TDengine/source/util/src/tqueue.c

589 lines
16 KiB
C
Raw Normal View History

2020-02-25 07:26:29 +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-01-25 08:40:07 +00:00
#define _DEFAULT_SOURCE
#include "taoserror.h"
2022-02-27 03:05:46 +00:00
#include "tlog.h"
#include "tqueue.h"
2024-07-16 09:30:32 +00:00
#include "tutil.h"
2024-08-13 03:18:29 +00:00
int64_t tsQueueMemoryAllowed = 0;
int64_t tsQueueMemoryUsed = 0;
int64_t tsApplyMemoryAllowed = 0;
int64_t tsApplyMemoryUsed = 0;
2024-02-27 08:27:59 +00:00
struct STaosQueue {
STaosQnode *head;
STaosQnode *tail;
STaosQueue *next; // for queue set
STaosQset *qset; // for queue set
void *ahandle; // for queue set
FItem itemFp;
FItems itemsFp;
int32_t numOfItems;
feat: support customized taos/taosd (#29736) * feat: support TDAcoreOS * chore: cmake options for TD_ACORE * chore: disable lemon for TD_ACORE * chore: add lzma2 and msvcregex * chore: cmake for lzma2 * chore: adapt for TD_ACORE * chore: adapt strcasecmp for TD_ACORE * chore: adapt for geos/threadName * chore: build adapt for TD_ACORE * chore: build adapt for TD_ACORE * chore: build adapt for TD_ACORE * chore: build adapt for TD_ACORE * chore: build adapt for TD_ACORE termio * chore: refact transComm.h for TD_ACORE * chore: refact transportInt.h for TD_ACORE * chore: refact trans.c for TD_ACORE * chore: refact trpc.h for TD_ACORE * chore: refact transCli.c/transComm.c/transSvr.c for TD_ACORE * chore: refact uv.h for TD_ACORE * chore: refact geosWrapper.h for TD_ACORE * chore: refact token/builtins/udf for TD_ACORE * chore: refact rocks for TD_ACORE * chore: refact tsdbCache.c for TD_ACORE, use LRU cache for last/last_row, not use rocksdb * chore: refact FAIL to _ERR to solve conflicts for TD_ACORE * chore: restore lemon.c/lempar.c * chore: support build lemon for TD_ACORE * chore: refact trpc and siginfo_t for TD_ACORE * chore: refact timezone for TD_ACORE * chore: refact lz4 for TD_ACORE * chore: refact TD_ACORE to make compile pass * chore: code optimization for TD_ASTRA * feat: support run taos with taosd integrated * feat: support invoke taos shell * feat: support invoke taos shell * feat: support invoke taos shell * chore: code optimization * chore: fix undefined reference problem os TD_ASTRA * chore: resolve compile problem for TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix getpid * chore: fix typo * chore: set stack size and ajust min pack size for TD_ASTRA * chore: fix pthread create parameters * chore: chmod adapt for TD_ASTRA * chore: fix trans compile problem * chore: adapt chmod for TD_ASTRA * chore: byte alignment for TD_ASTRA * chore: more code for adaption of TD_ASTRA * chore: more code for adaption of TD_ASTRA * chore: more code for adaption of TD_ASTRA * chore: byte alignment for TD_ASTRA * chore: conditional compile option * chore: adapt for TD_ASTRA * chore: adjust taosPId and msvcregex for TD_ASTRA * chore: log dir separator for wal build name * chore: fix type of pointer parameter * chore: fix compile problem of tsdbGetS3Size * enh: get last ver from wal log for TD_ASTRA * enh: refact wal meta ver * enh: refact wal meta ver * fix: typo of taosUcs4Compare * enh: process return value of CI * chore: more code for TD_ASTRA adaption * chore: return value of taosCloseFile in walMeta.c * chore: fix compile problem * chore: fix compile problem of TD_ASTRA * fix: update macro for tq and stream task * chore: code optimization for TD_ASTRA * chore: restore create log and init cfg interface * chore: restore strncasecmp and strcasecmp * fix: adjust the field position of SDataBlockInfo * fix: pragma pack min size * fix: pragma pack min size * chore: more code for TD_ASTRA adaption * fix: type of parameters * chore: adapt strncasecmp and strcasecmp for TD_ASTRA * chore: restore interface of init log * enh: pack push optimization * fix: taos init cfg * add astra support * fix: fetch the value of suid * chore: switch of build with udf * add temp code * chore: more code for TD_ASTRA adaption * chore: add macro ERRNO to replace errno * chore: bytes align for TD_ASTRA * fix: remove obsolete codes * enh: support USE_UDF macro * fix compile error * fix: resolve redefinition problem * fix: compile problem of log.cpp * fix: compile problem of osTimezone * fix: resolve compile problem of udf * fix: pragma definition on windows * fix: ucs4 and stpncpy for TD_ASTRA * fix: memory align problem for TD_ASTRA * enh: solve memory leak for TD_ASTRA_RPC * fix: compile problem of taosSetInt64Aligned * fix: restore mndSubscribe.c * fix: scalar for udf * chore: code adaption for TD_ASTRA * chore: code optimization for TD_ASTRA * fix: typo of add definition * fix: typo of macro in tudf.h * chore: remove void to make CI pass * enh: move macro from cmake.platform to cmake.options * enh: byte align for hash node and error code * chore: restore the size for lru cache * enh: restore some code about pack push * chore: restore the pack push in tmsg.h * fix: add macro of pack pop for windows --------- Co-authored-by: yihaoDeng <luomoxyz@126.com>
2025-03-14 05:32:13 +00:00
int64_t memOfItems;
2024-02-27 08:27:59 +00:00
int64_t threadId;
int64_t memLimit;
int64_t itemLimit;
feat: support customized taos/taosd (#29736) * feat: support TDAcoreOS * chore: cmake options for TD_ACORE * chore: disable lemon for TD_ACORE * chore: add lzma2 and msvcregex * chore: cmake for lzma2 * chore: adapt for TD_ACORE * chore: adapt strcasecmp for TD_ACORE * chore: adapt for geos/threadName * chore: build adapt for TD_ACORE * chore: build adapt for TD_ACORE * chore: build adapt for TD_ACORE * chore: build adapt for TD_ACORE * chore: build adapt for TD_ACORE termio * chore: refact transComm.h for TD_ACORE * chore: refact transportInt.h for TD_ACORE * chore: refact trans.c for TD_ACORE * chore: refact trpc.h for TD_ACORE * chore: refact transCli.c/transComm.c/transSvr.c for TD_ACORE * chore: refact uv.h for TD_ACORE * chore: refact geosWrapper.h for TD_ACORE * chore: refact token/builtins/udf for TD_ACORE * chore: refact rocks for TD_ACORE * chore: refact tsdbCache.c for TD_ACORE, use LRU cache for last/last_row, not use rocksdb * chore: refact FAIL to _ERR to solve conflicts for TD_ACORE * chore: restore lemon.c/lempar.c * chore: support build lemon for TD_ACORE * chore: refact trpc and siginfo_t for TD_ACORE * chore: refact timezone for TD_ACORE * chore: refact lz4 for TD_ACORE * chore: refact TD_ACORE to make compile pass * chore: code optimization for TD_ASTRA * feat: support run taos with taosd integrated * feat: support invoke taos shell * feat: support invoke taos shell * feat: support invoke taos shell * chore: code optimization * chore: fix undefined reference problem os TD_ASTRA * chore: resolve compile problem for TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix getpid * chore: fix typo * chore: set stack size and ajust min pack size for TD_ASTRA * chore: fix pthread create parameters * chore: chmod adapt for TD_ASTRA * chore: fix trans compile problem * chore: adapt chmod for TD_ASTRA * chore: byte alignment for TD_ASTRA * chore: more code for adaption of TD_ASTRA * chore: more code for adaption of TD_ASTRA * chore: more code for adaption of TD_ASTRA * chore: byte alignment for TD_ASTRA * chore: conditional compile option * chore: adapt for TD_ASTRA * chore: adjust taosPId and msvcregex for TD_ASTRA * chore: log dir separator for wal build name * chore: fix type of pointer parameter * chore: fix compile problem of tsdbGetS3Size * enh: get last ver from wal log for TD_ASTRA * enh: refact wal meta ver * enh: refact wal meta ver * fix: typo of taosUcs4Compare * enh: process return value of CI * chore: more code for TD_ASTRA adaption * chore: return value of taosCloseFile in walMeta.c * chore: fix compile problem * chore: fix compile problem of TD_ASTRA * fix: update macro for tq and stream task * chore: code optimization for TD_ASTRA * chore: restore create log and init cfg interface * chore: restore strncasecmp and strcasecmp * fix: adjust the field position of SDataBlockInfo * fix: pragma pack min size * fix: pragma pack min size * chore: more code for TD_ASTRA adaption * fix: type of parameters * chore: adapt strncasecmp and strcasecmp for TD_ASTRA * chore: restore interface of init log * enh: pack push optimization * fix: taos init cfg * add astra support * fix: fetch the value of suid * chore: switch of build with udf * add temp code * chore: more code for TD_ASTRA adaption * chore: add macro ERRNO to replace errno * chore: bytes align for TD_ASTRA * fix: remove obsolete codes * enh: support USE_UDF macro * fix compile error * fix: resolve redefinition problem * fix: compile problem of log.cpp * fix: compile problem of osTimezone * fix: resolve compile problem of udf * fix: pragma definition on windows * fix: ucs4 and stpncpy for TD_ASTRA * fix: memory align problem for TD_ASTRA * enh: solve memory leak for TD_ASTRA_RPC * fix: compile problem of taosSetInt64Aligned * fix: restore mndSubscribe.c * fix: scalar for udf * chore: code adaption for TD_ASTRA * chore: code optimization for TD_ASTRA * fix: typo of add definition * fix: typo of macro in tudf.h * chore: remove void to make CI pass * enh: move macro from cmake.platform to cmake.options * enh: byte align for hash node and error code * chore: restore the size for lru cache * enh: restore some code about pack push * chore: restore the pack push in tmsg.h * fix: add macro of pack pop for windows --------- Co-authored-by: yihaoDeng <luomoxyz@126.com>
2025-03-14 05:32:13 +00:00
TdThreadMutex mutex;
2024-02-27 08:27:59 +00:00
};
struct STaosQset {
STaosQueue *head;
STaosQueue *current;
TdThreadMutex mutex;
tsem_t sem;
int32_t numOfQueues;
int32_t numOfItems;
};
struct STaosQall {
STaosQnode *current;
STaosQnode *start;
int32_t numOfItems;
int64_t memOfItems;
int32_t unAccessedNumOfItems;
int64_t unAccessMemOfItems;
};
2023-04-04 07:20:05 +00:00
void taosSetQueueMemoryCapacity(STaosQueue *queue, int64_t cap) { queue->memLimit = cap; }
void taosSetQueueCapacity(STaosQueue *queue, int64_t size) { queue->itemLimit = size; }
2024-07-16 09:30:32 +00:00
int32_t taosOpenQueue(STaosQueue **queue) {
*queue = taosMemoryCalloc(1, sizeof(STaosQueue));
if (*queue == NULL) {
2024-09-11 06:11:51 +00:00
return terrno;
2020-02-25 07:26:29 +00:00
}
2024-07-16 09:30:32 +00:00
int32_t code = taosThreadMutexInit(&(*queue)->mutex, NULL);
if (code) {
taosMemoryFreeClear(*queue);
return (terrno = TAOS_SYSTEM_ERROR(code));
2022-01-25 08:40:07 +00:00
}
2022-01-25 08:40:07 +00:00
uDebug("queue:%p is opened", queue);
2024-07-16 09:30:32 +00:00
return 0;
2020-03-07 14:57:25 +00:00
}
2020-02-25 07:26:29 +00:00
2022-01-25 09:14:24 +00:00
void taosSetQueueFp(STaosQueue *queue, FItem itemFp, FItems itemsFp) {
if (queue == NULL) return;
2021-11-01 11:49:44 +00:00
queue->itemFp = itemFp;
queue->itemsFp = itemsFp;
2021-10-29 09:11:15 +00:00
}
void taosCloseQueue(STaosQueue *queue) {
if (queue == NULL) return;
2020-03-07 14:57:25 +00:00
STaosQnode *pTemp;
2022-06-06 08:34:12 +00:00
STaosQset *qset;
2024-07-27 10:28:26 +00:00
(void)taosThreadMutexLock(&queue->mutex);
2021-10-29 09:11:15 +00:00
STaosQnode *pNode = queue->head;
2020-03-07 14:57:25 +00:00
queue->head = NULL;
qset = queue->qset;
2024-07-27 10:28:26 +00:00
(void)taosThreadMutexUnlock(&queue->mutex);
2020-02-25 07:26:29 +00:00
2022-01-25 08:40:07 +00:00
if (queue->qset) {
taosRemoveFromQset(qset, queue);
}
2020-02-25 07:26:29 +00:00
2020-03-07 14:57:25 +00:00
while (pNode) {
pTemp = pNode;
pNode = pNode->next;
2022-03-25 16:29:53 +00:00
taosMemoryFree(pTemp);
2020-02-25 07:26:29 +00:00
}
2024-07-29 12:14:15 +00:00
(void)taosThreadMutexDestroy(&queue->mutex);
2022-03-25 16:29:53 +00:00
taosMemoryFree(queue);
2020-08-01 11:49:58 +00:00
2022-01-25 08:40:07 +00:00
uDebug("queue:%p is closed", queue);
2020-03-07 14:57:25 +00:00
}
2020-02-25 07:26:29 +00:00
bool taosQueueEmpty(STaosQueue *queue) {
if (queue == NULL) return true;
2021-11-04 09:03:24 +00:00
bool empty = false;
2024-07-27 10:28:26 +00:00
(void)taosThreadMutexLock(&queue->mutex);
2023-05-08 07:43:44 +00:00
if (queue->head == NULL && queue->tail == NULL && queue->numOfItems == 0 /*&& queue->memOfItems == 0*/) {
2021-11-04 09:03:24 +00:00
empty = true;
}
2024-07-27 10:28:26 +00:00
(void)taosThreadMutexUnlock(&queue->mutex);
2021-11-04 09:03:24 +00:00
return empty;
}
void taosUpdateItemSize(STaosQueue *queue, int32_t items) {
if (queue == NULL) return;
2024-07-27 10:28:26 +00:00
(void)taosThreadMutexLock(&queue->mutex);
queue->numOfItems -= items;
2024-07-27 10:28:26 +00:00
(void)taosThreadMutexUnlock(&queue->mutex);
}
int32_t taosQueueItemSize(STaosQueue *queue) {
if (queue == NULL) return 0;
2024-07-27 10:28:26 +00:00
(void)taosThreadMutexLock(&queue->mutex);
int32_t numOfItems = queue->numOfItems;
2024-07-27 10:28:26 +00:00
(void)taosThreadMutexUnlock(&queue->mutex);
2022-10-25 07:55:19 +00:00
uTrace("queue:%p, numOfItems:%d memOfItems:%" PRId64, queue, queue->numOfItems, queue->memOfItems);
return numOfItems;
}
int64_t taosQueueMemorySize(STaosQueue *queue) {
2024-07-27 10:28:26 +00:00
(void)taosThreadMutexLock(&queue->mutex);
int64_t memOfItems = queue->memOfItems;
2024-07-27 10:28:26 +00:00
(void)taosThreadMutexUnlock(&queue->mutex);
return memOfItems;
}
2024-07-16 09:30:32 +00:00
int32_t taosAllocateQitem(int32_t size, EQItype itype, int64_t dataSize, void **item) {
int64_t alloced = -1;
2025-01-21 10:13:13 +00:00
if (itype == RPC_QITEM) {
alloced = atomic_add_fetch_64(&tsQueueMemoryUsed, size + dataSize);
2025-01-21 10:13:13 +00:00
if (alloced > tsQueueMemoryAllowed) {
2024-08-13 03:18:29 +00:00
uError("failed to alloc qitem, size:%" PRId64 " alloc:%" PRId64 " allowed:%" PRId64, size + dataSize, alloced,
tsQueueMemoryAllowed);
(void)atomic_sub_fetch_64(&tsQueueMemoryUsed, size + dataSize);
return (terrno = TSDB_CODE_OUT_OF_RPC_MEMORY_QUEUE);
}
} else if (itype == APPLY_QITEM) {
alloced = atomic_add_fetch_64(&tsApplyMemoryUsed, size + dataSize);
if (alloced > tsApplyMemoryAllowed) {
uDebug("failed to alloc qitem, size:%" PRId64 " alloc:%" PRId64 " allowed:%" PRId64, size + dataSize, alloced,
tsApplyMemoryAllowed);
(void)atomic_sub_fetch_64(&tsApplyMemoryUsed, size + dataSize);
2025-01-21 03:37:26 +00:00
return (terrno = TSDB_CODE_OUT_OF_RPC_MEMORY_QUEUE);
}
2024-08-13 03:18:29 +00:00
}
2024-07-16 09:30:32 +00:00
2024-08-13 03:18:29 +00:00
*item = NULL;
2022-03-25 16:29:53 +00:00
STaosQnode *pNode = taosMemoryCalloc(1, sizeof(STaosQnode) + size);
2025-01-21 04:34:47 +00:00
if (pNode == NULL) {
if (itype == RPC_QITEM) {
(void)atomic_sub_fetch_64(&tsQueueMemoryUsed, size + dataSize);
} else if (itype == APPLY_QITEM) {
(void)atomic_sub_fetch_64(&tsApplyMemoryUsed, size + dataSize);
}
return terrno;
2022-01-25 08:40:07 +00:00
}
2021-10-29 09:11:15 +00:00
2022-12-10 06:02:57 +00:00
pNode->dataSize = dataSize;
2022-09-27 08:02:40 +00:00
pNode->size = size;
pNode->itype = itype;
pNode->timestamp = taosGetTimestampUs();
2024-08-13 03:18:29 +00:00
uTrace("item:%p, node:%p is allocated, alloc:%" PRId64, pNode->item, pNode, alloced);
2024-07-16 09:30:32 +00:00
*item = pNode->item;
return 0;
2020-03-15 05:44:07 +00:00
}
2020-02-25 07:26:29 +00:00
2022-01-25 09:14:24 +00:00
void taosFreeQitem(void *pItem) {
if (pItem == NULL) return;
2020-03-15 05:44:07 +00:00
STaosQnode *pNode = (STaosQnode *)((char *)pItem - sizeof(STaosQnode));
int64_t alloced = -1;
if (pNode->itype == RPC_QITEM) {
alloced = atomic_sub_fetch_64(&tsQueueMemoryUsed, pNode->size + pNode->dataSize);
} else if (pNode->itype == APPLY_QITEM) {
alloced = atomic_sub_fetch_64(&tsApplyMemoryUsed, pNode->size + pNode->dataSize);
}
2024-08-13 03:18:29 +00:00
uTrace("item:%p, node:%p is freed, alloc:%" PRId64, pItem, pNode, alloced);
taosMemoryFree(pNode);
2020-03-15 05:44:07 +00:00
}
2020-02-25 07:26:29 +00:00
2023-04-04 07:20:05 +00:00
int32_t taosWriteQitem(STaosQueue *queue, void *pItem) {
int32_t code = 0;
STaosQnode *pNode = (STaosQnode *)(((char *)pItem) - sizeof(STaosQnode));
2024-01-31 07:10:01 +00:00
pNode->timestamp = taosGetTimestampUs();
pNode->next = NULL;
2020-02-25 07:26:29 +00:00
2024-07-27 10:28:26 +00:00
(void)taosThreadMutexLock(&queue->mutex);
2023-05-08 07:43:44 +00:00
if (queue->memLimit > 0 && (queue->memOfItems + pNode->size + pNode->dataSize) > queue->memLimit) {
2023-04-04 07:20:05 +00:00
code = TSDB_CODE_UTIL_QUEUE_OUT_OF_MEMORY;
2025-02-26 03:34:50 +00:00
uError("item:%p, failed to put into queue:%p, queue mem limit:%" PRId64 ", reason:%s" PRId64, pItem, queue,
2023-04-04 07:20:05 +00:00
queue->memLimit, tstrerror(code));
2024-07-27 10:28:26 +00:00
(void)taosThreadMutexUnlock(&queue->mutex);
2023-04-04 07:20:05 +00:00
return code;
2023-04-04 12:38:56 +00:00
} else if (queue->itemLimit > 0 && queue->numOfItems + 1 > queue->itemLimit) {
2023-04-04 07:20:05 +00:00
code = TSDB_CODE_UTIL_QUEUE_OUT_OF_MEMORY;
2025-02-26 03:34:50 +00:00
uError("item:%p, failed to put into queue:%p, queue size limit:%" PRId64 ", reason:%s" PRId64, pItem, queue,
2023-04-04 07:20:05 +00:00
queue->itemLimit, tstrerror(code));
2024-07-27 10:28:26 +00:00
(void)taosThreadMutexUnlock(&queue->mutex);
2023-04-04 07:20:05 +00:00
return code;
}
2020-02-25 07:26:29 +00:00
2020-03-07 14:57:25 +00:00
if (queue->tail) {
queue->tail->next = pNode;
queue->tail = pNode;
} else {
queue->head = pNode;
2021-10-29 09:11:15 +00:00
queue->tail = pNode;
2020-03-07 14:57:25 +00:00
}
queue->numOfItems++;
queue->memOfItems += (pNode->size + pNode->dataSize);
2024-07-16 09:30:32 +00:00
if (queue->qset) {
2024-07-29 12:14:15 +00:00
(void)atomic_add_fetch_32(&queue->qset->numOfItems, 1);
2024-07-16 09:30:32 +00:00
}
2023-04-04 07:20:05 +00:00
2025-02-26 03:34:50 +00:00
uTrace("item:%p, is put into queue:%p, items:%d mem:%" PRId64, pItem, queue, queue->numOfItems, queue->memOfItems);
2024-07-27 10:28:26 +00:00
(void)taosThreadMutexUnlock(&queue->mutex);
2020-03-08 02:28:30 +00:00
2024-07-16 09:30:32 +00:00
if (queue->qset) {
2024-09-24 08:48:07 +00:00
if (tsem_post(&queue->qset->sem) != 0) {
uError("failed to post semaphore for queue set:%p", queue->qset);
}
2024-07-16 09:30:32 +00:00
}
2023-04-04 07:20:05 +00:00
return code;
2020-02-25 07:26:29 +00:00
}
2024-09-12 06:17:14 +00:00
void taosReadQitem(STaosQueue *queue, void **ppItem) {
2020-03-07 14:57:25 +00:00
STaosQnode *pNode = NULL;
2020-02-25 07:26:29 +00:00
2024-07-27 10:28:26 +00:00
(void)taosThreadMutexLock(&queue->mutex);
2020-02-25 07:26:29 +00:00
2020-03-07 14:57:25 +00:00
if (queue->head) {
2021-10-29 09:11:15 +00:00
pNode = queue->head;
*ppItem = pNode->item;
2021-10-29 09:11:15 +00:00
queue->head = pNode->next;
2024-07-16 09:30:32 +00:00
if (queue->head == NULL) {
queue->tail = NULL;
}
2021-10-29 09:11:15 +00:00
queue->numOfItems--;
2023-05-08 07:43:44 +00:00
queue->memOfItems -= (pNode->size + pNode->dataSize);
2024-07-16 09:30:32 +00:00
if (queue->qset) {
2024-07-29 12:14:15 +00:00
(void)atomic_sub_fetch_32(&queue->qset->numOfItems, 1);
2024-07-16 09:30:32 +00:00
}
2025-02-26 03:34:50 +00:00
uTrace("item:%p, is read out from queue:%p, items:%d mem:%" PRId64, *ppItem, queue, queue->numOfItems,
queue->memOfItems);
2021-10-29 09:11:15 +00:00
}
2020-02-25 07:26:29 +00:00
2024-07-27 10:28:26 +00:00
(void)taosThreadMutexUnlock(&queue->mutex);
2020-03-07 14:57:25 +00:00
}
2020-02-25 07:26:29 +00:00
2024-07-16 09:30:32 +00:00
int32_t taosAllocateQall(STaosQall **qall) {
*qall = taosMemoryCalloc(1, sizeof(STaosQall));
if (*qall == NULL) {
2024-09-11 06:11:51 +00:00
return terrno;
}
2024-07-16 09:30:32 +00:00
return 0;
}
2022-03-25 16:29:53 +00:00
void taosFreeQall(STaosQall *qall) { taosMemoryFree(qall); }
int32_t taosReadAllQitems(STaosQueue *queue, STaosQall *qall) {
int32_t numOfItems = 0;
bool empty;
2020-03-07 14:57:25 +00:00
2024-07-27 10:28:26 +00:00
(void)taosThreadMutexLock(&queue->mutex);
2020-03-07 14:57:25 +00:00
2021-07-15 05:03:25 +00:00
empty = queue->head == NULL;
if (!empty) {
memset(qall, 0, sizeof(STaosQall));
qall->current = queue->head;
qall->start = queue->head;
qall->numOfItems = queue->numOfItems;
2023-10-21 08:20:03 +00:00
qall->memOfItems = queue->memOfItems;
qall->unAccessedNumOfItems = queue->numOfItems;
qall->unAccessMemOfItems = queue->memOfItems;
numOfItems = qall->numOfItems;
queue->head = NULL;
queue->tail = NULL;
queue->numOfItems = 0;
queue->memOfItems = 0;
uTrace("read %d items from queue:%p, items:%d mem:%" PRId64, numOfItems, queue, queue->numOfItems,
queue->memOfItems);
2024-07-16 09:30:32 +00:00
if (queue->qset) {
2024-07-29 12:14:15 +00:00
(void)atomic_sub_fetch_32(&queue->qset->numOfItems, qall->numOfItems);
2024-07-16 09:30:32 +00:00
}
2021-07-15 05:03:25 +00:00
}
2020-02-25 07:26:29 +00:00
2024-07-27 10:28:26 +00:00
(void)taosThreadMutexUnlock(&queue->mutex);
2021-07-15 05:03:25 +00:00
// if source queue is empty, we set destination qall to empty too.
if (empty) {
qall->current = NULL;
qall->start = NULL;
qall->numOfItems = 0;
}
return numOfItems;
2020-03-07 14:57:25 +00:00
}
2020-02-25 07:26:29 +00:00
int32_t taosGetQitem(STaosQall *qall, void **ppItem) {
2020-03-07 14:57:25 +00:00
STaosQnode *pNode;
int32_t num = 0;
2020-02-25 07:26:29 +00:00
2020-03-07 14:57:25 +00:00
pNode = qall->current;
2021-10-29 09:11:15 +00:00
if (pNode) qall->current = pNode->next;
2020-03-07 14:57:25 +00:00
if (pNode) {
*ppItem = pNode->item;
2020-03-07 14:57:25 +00:00
num = 1;
2023-10-21 08:20:03 +00:00
qall->unAccessedNumOfItems -= 1;
qall->unAccessMemOfItems -= pNode->dataSize;
2025-02-26 03:34:50 +00:00
uTrace("item:%p, is fetched", *ppItem);
2022-06-06 08:34:12 +00:00
} else {
*ppItem = NULL;
2020-02-25 07:26:29 +00:00
}
2020-03-07 14:57:25 +00:00
return num;
2020-02-25 07:26:29 +00:00
}
2024-07-16 09:30:32 +00:00
int32_t taosOpenQset(STaosQset **qset) {
*qset = taosMemoryCalloc(sizeof(STaosQset), 1);
if (*qset == NULL) {
2024-09-11 06:11:51 +00:00
return terrno;
2020-02-25 07:26:29 +00:00
}
2024-07-29 12:14:15 +00:00
(void)taosThreadMutexInit(&(*qset)->mutex, NULL);
2024-09-24 08:48:07 +00:00
if (tsem_init(&(*qset)->sem, 0, 0) != 0) {
taosMemoryFree(*qset);
return terrno;
}
2020-02-25 07:26:29 +00:00
2025-02-27 06:27:46 +00:00
uDebug("qset:%p, is opened", qset);
2024-07-16 09:30:32 +00:00
return 0;
2020-03-07 14:57:25 +00:00
}
2020-02-25 07:26:29 +00:00
void taosCloseQset(STaosQset *qset) {
if (qset == NULL) return;
// remove all the queues from qset
2024-07-27 10:28:26 +00:00
(void)taosThreadMutexLock(&qset->mutex);
while (qset->head) {
STaosQueue *queue = qset->head;
qset->head = qset->head->next;
queue->qset = NULL;
queue->next = NULL;
}
2024-07-27 10:28:26 +00:00
(void)taosThreadMutexUnlock(&qset->mutex);
2024-07-29 12:14:15 +00:00
(void)taosThreadMutexDestroy(&qset->mutex);
2024-09-24 08:48:07 +00:00
if (tsem_destroy(&qset->sem) != 0) {
uError("failed to destroy semaphore for qset:%p", qset);
}
2022-03-25 16:29:53 +00:00
taosMemoryFree(qset);
2025-02-27 06:27:46 +00:00
uDebug("qset:%p, is closed", qset);
2020-03-07 14:57:25 +00:00
}
2020-05-20 06:02:47 +00:00
// tsem_post 'qset->sem', so that reader threads waiting for it
// resumes execution and return, should only be used to signal the
// thread to exit.
void taosQsetThreadResume(STaosQset *qset) {
2020-10-11 07:51:17 +00:00
uDebug("qset:%p, it will exit", qset);
2024-09-24 08:48:07 +00:00
if (tsem_post(&qset->sem) != 0) {
uError("failed to post semaphore for qset:%p", qset);
}
2020-05-20 06:02:47 +00:00
}
int32_t taosAddIntoQset(STaosQset *qset, STaosQueue *queue, void *ahandle) {
2024-08-14 09:50:20 +00:00
if (queue->qset) return TSDB_CODE_INVALID_PARA;
2020-03-07 14:57:25 +00:00
2024-07-27 10:28:26 +00:00
(void)taosThreadMutexLock(&qset->mutex);
2020-03-07 14:57:25 +00:00
queue->next = qset->head;
2020-03-15 05:44:07 +00:00
queue->ahandle = ahandle;
2020-03-07 14:57:25 +00:00
qset->head = queue;
qset->numOfQueues++;
2024-07-27 10:28:26 +00:00
(void)taosThreadMutexLock(&queue->mutex);
2024-07-29 12:14:15 +00:00
(void)atomic_add_fetch_32(&qset->numOfItems, queue->numOfItems);
2020-03-07 14:57:25 +00:00
queue->qset = qset;
2024-07-27 10:28:26 +00:00
(void)taosThreadMutexUnlock(&queue->mutex);
2020-03-07 14:57:25 +00:00
2024-07-27 10:28:26 +00:00
(void)taosThreadMutexUnlock(&qset->mutex);
2020-02-25 07:26:29 +00:00
2025-02-27 06:27:46 +00:00
uTrace("queue:%p, is added into qset:%p", queue, qset);
2020-02-25 07:26:29 +00:00
return 0;
}
void taosRemoveFromQset(STaosQset *qset, STaosQueue *queue) {
STaosQueue *tqueue = NULL;
2020-03-07 14:57:25 +00:00
2024-07-27 10:28:26 +00:00
(void)taosThreadMutexLock(&qset->mutex);
2020-03-07 14:57:25 +00:00
if (qset->head) {
if (qset->head == queue) {
qset->head = qset->head->next;
tqueue = queue;
2020-03-07 14:57:25 +00:00
} else {
STaosQueue *prev = qset->head;
tqueue = qset->head->next;
while (tqueue) {
2021-10-29 09:11:15 +00:00
if (tqueue == queue) {
2020-03-07 14:57:25 +00:00
prev->next = tqueue->next;
break;
2020-03-07 14:57:25 +00:00
} else {
prev = tqueue;
tqueue = tqueue->next;
}
}
}
if (tqueue) {
if (qset->current == queue) qset->current = tqueue->next;
qset->numOfQueues--;
2024-07-27 10:28:26 +00:00
(void)taosThreadMutexLock(&queue->mutex);
2024-07-29 12:14:15 +00:00
(void)atomic_sub_fetch_32(&qset->numOfItems, queue->numOfItems);
queue->qset = NULL;
queue->next = NULL;
2024-07-27 10:28:26 +00:00
(void)taosThreadMutexUnlock(&queue->mutex);
}
2021-10-29 09:11:15 +00:00
}
2024-07-27 10:28:26 +00:00
(void)taosThreadMutexUnlock(&qset->mutex);
2020-08-01 11:49:58 +00:00
2025-02-27 06:27:46 +00:00
uDebug("queue:%p, is removed from qset:%p", queue, qset);
2020-03-07 14:57:25 +00:00
}
int32_t taosReadQitemFromQset(STaosQset *qset, void **ppItem, SQueueInfo *qinfo) {
2020-03-07 14:57:25 +00:00
STaosQnode *pNode = NULL;
int32_t code = 0;
2021-10-29 09:11:15 +00:00
2024-09-24 08:48:07 +00:00
if (tsem_wait(&qset->sem) != 0) {
uError("failed to wait semaphore for qset:%p", qset);
}
2024-07-27 10:28:26 +00:00
(void)taosThreadMutexLock(&qset->mutex);
2020-03-07 14:57:25 +00:00
for (int32_t i = 0; i < qset->numOfQueues; ++i) {
2021-10-29 09:11:15 +00:00
if (qset->current == NULL) qset->current = qset->head;
2020-03-07 14:57:25 +00:00
STaosQueue *queue = qset->current;
2020-03-08 02:28:30 +00:00
if (queue) qset->current = queue->next;
if (queue == NULL) break;
if (queue->head == NULL) continue;
2020-03-07 14:57:25 +00:00
2024-07-27 10:28:26 +00:00
(void)taosThreadMutexLock(&queue->mutex);
2020-03-07 14:57:25 +00:00
if (queue->head) {
2021-10-29 09:11:15 +00:00
pNode = queue->head;
*ppItem = pNode->item;
qinfo->ahandle = queue->ahandle;
qinfo->fp = queue->itemFp;
qinfo->queue = queue;
qinfo->timestamp = pNode->timestamp;
2022-01-25 08:40:07 +00:00
2021-10-29 09:11:15 +00:00
queue->head = pNode->next;
if (queue->head == NULL) queue->tail = NULL;
// queue->numOfItems--;
2023-05-08 07:43:44 +00:00
queue->memOfItems -= (pNode->size + pNode->dataSize);
2024-07-29 12:14:15 +00:00
(void)atomic_sub_fetch_32(&qset->numOfItems, 1);
2021-10-29 09:11:15 +00:00
code = 1;
2025-02-26 03:34:50 +00:00
uTrace("item:%p, is read out from queue:%p, items:%d mem:%" PRId64, *ppItem, queue, queue->numOfItems - 1,
queue->memOfItems);
2021-10-29 09:11:15 +00:00
}
2020-03-07 14:57:25 +00:00
2024-07-27 10:28:26 +00:00
(void)taosThreadMutexUnlock(&queue->mutex);
2020-03-07 14:57:25 +00:00
if (pNode) break;
}
2024-07-27 10:28:26 +00:00
(void)taosThreadMutexUnlock(&qset->mutex);
2020-04-11 14:28:58 +00:00
2021-10-29 09:11:15 +00:00
return code;
2020-03-07 14:57:25 +00:00
}
int32_t taosReadAllQitemsFromQset(STaosQset *qset, STaosQall *qall, SQueueInfo *qinfo) {
2020-03-07 14:57:25 +00:00
STaosQueue *queue;
int32_t code = 0;
2020-03-07 14:57:25 +00:00
2024-09-24 08:48:07 +00:00
if (tsem_wait(&qset->sem) != 0) {
uError("failed to wait semaphore for qset:%p", qset);
}
2024-07-27 10:28:26 +00:00
(void)taosThreadMutexLock(&qset->mutex);
2020-04-11 14:28:58 +00:00
for (int32_t i = 0; i < qset->numOfQueues; ++i) {
if (qset->current == NULL) qset->current = qset->head;
2020-03-07 14:57:25 +00:00
queue = qset->current;
2020-03-08 02:28:30 +00:00
if (queue) qset->current = queue->next;
if (queue == NULL) break;
if (queue->head == NULL) continue;
2020-03-07 14:57:25 +00:00
2024-07-27 10:28:26 +00:00
(void)taosThreadMutexLock(&queue->mutex);
2020-03-07 14:57:25 +00:00
if (queue->head) {
qall->current = queue->head;
qall->start = queue->head;
qall->numOfItems = queue->numOfItems;
2023-10-21 08:20:03 +00:00
qall->memOfItems = queue->memOfItems;
2024-07-04 09:11:53 +00:00
qall->unAccessedNumOfItems = queue->numOfItems;
qall->unAccessMemOfItems = queue->memOfItems;
2023-10-21 08:20:03 +00:00
code = qall->numOfItems;
qinfo->ahandle = queue->ahandle;
qinfo->fp = queue->itemsFp;
qinfo->queue = queue;
2024-01-31 07:10:01 +00:00
qinfo->timestamp = queue->head->timestamp;
2021-10-29 09:11:15 +00:00
queue->head = NULL;
queue->tail = NULL;
// queue->numOfItems = 0;
queue->memOfItems = 0;
uTrace("read %d items from queue:%p, items:0 mem:%" PRId64, code, queue, queue->memOfItems);
2024-07-29 12:14:15 +00:00
(void)atomic_sub_fetch_32(&qset->numOfItems, qall->numOfItems);
2022-01-25 10:29:47 +00:00
for (int32_t j = 1; j < qall->numOfItems; ++j) {
2024-09-24 08:48:07 +00:00
if (tsem_wait(&qset->sem) != 0) {
uError("failed to wait semaphore for qset:%p", qset);
}
2022-01-25 10:29:47 +00:00
}
}
2020-03-07 14:57:25 +00:00
2024-07-27 10:28:26 +00:00
(void)taosThreadMutexUnlock(&queue->mutex);
2020-03-07 14:57:25 +00:00
if (code != 0) break;
2020-03-07 14:57:25 +00:00
}
2020-02-25 07:26:29 +00:00
2024-07-27 10:28:26 +00:00
(void)taosThreadMutexUnlock(&qset->mutex);
2020-03-07 14:57:25 +00:00
return code;
}
2020-02-25 07:26:29 +00:00
2022-10-20 03:07:33 +00:00
int32_t taosQallItemSize(STaosQall *qall) { return qall->numOfItems; }
2023-10-21 08:20:03 +00:00
int64_t taosQallMemSize(STaosQall *qall) { return qall->memOfItems; }
2024-01-31 07:10:01 +00:00
int64_t taosQallUnAccessedItemSize(STaosQall *qall) { return qall->unAccessedNumOfItems; }
int64_t taosQallUnAccessedMemSize(STaosQall *qall) { return qall->unAccessMemOfItems; }
2023-10-21 08:20:03 +00:00
2022-10-20 06:00:52 +00:00
void taosResetQitems(STaosQall *qall) { qall->current = qall->start; }
int32_t taosGetQueueNumber(STaosQset *qset) { return qset->numOfQueues; }
2022-10-20 03:07:33 +00:00
2024-07-16 09:30:32 +00:00
void taosQueueSetThreadId(STaosQueue *pQueue, int64_t threadId) { pQueue->threadId = threadId; }
2024-02-27 08:27:59 +00:00
int64_t taosQueueGetThreadId(STaosQueue *pQueue) { return pQueue->threadId; }
2022-10-20 03:07:33 +00:00
#if 0
2022-01-25 09:14:24 +00:00
void taosResetQsetThread(STaosQset *qset, void *pItem) {
if (pItem == NULL) return;
STaosQnode *pNode = (STaosQnode *)((char *)pItem - sizeof(STaosQnode));
2024-07-27 10:28:26 +00:00
(void)taosThreadMutexLock(&qset->mutex);
2022-01-25 10:29:47 +00:00
for (int32_t i = 0; i < pNode->queue->numOfItems; ++i) {
tsem_post(&qset->sem);
}
2024-07-27 10:28:26 +00:00
(void)taosThreadMutexUnlock(&qset->mutex);
2022-01-25 09:14:24 +00:00
}
2022-10-20 03:07:33 +00:00
#endif