diff --git a/utils/include/hdf_block_buffer.h b/utils/include/hdf_block_buffer.h new file mode 100644 index 0000000000000000000000000000000000000000..205897e25f3391eed1679a4285966a8ec80c4cde --- /dev/null +++ b/utils/include/hdf_block_buffer.h @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2021-2021 Huawei Device Co., Ltd. + * + * HDF is dual licensed: you can use it either under the terms of + * the GPL, or the BSD license, at your option. + * See the LICENSE file in the root of this repository for complete details. + */ + +#ifndef BLOCK_BUFFER_H +#define BLOCK_BUFFER_H + +#include +#include "hdf_slist.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct HdfBlockBuffer { + struct HdfSList link; + uint16_t position; + uint16_t dataSize; + uint8_t data[1]; +}; + +struct HdfBlockBuffer *HdfBlockBufferNew(uint16_t size); + +void HdfBlockBufferFree(struct BlockBuffer *buffer); + +uint16_t HdfBlockBufferGetDataSize(struct BlockBuffer *buffer); + +uint16_t HdfBlockBufferGetAvailableSize(struct BlockBuffer *buffer); + +uint16_t HdfBlockBufferSkipBytes(struct BlockBuffer *buffer, uint16_t bytes); + +uint8_t *HdfBlockBufferRead(struct BlockBuffer *buffer, uint16_t size); + +/* + * @brief read a byte value from buffer and move cursor to next. + * + * @param[in] buff the instance of gdk buffer. + * @param[in] ulOffset the offset from current cursor. + * + * @return the byte value that read from buffer. + */ +bool HdfBlockBufferGetc(struct BlockBuffer *buffer, uint8_t *outValue); + +/* + * @brief read a byte value from buffer and move cursor to next. + * + * @param[in] buff the instance of gdk buffer. + * @param[in] ulOffset the offset from current cursor. + * + * @return the byte value that read from buffer. + */ +bool HdfBlockBufferReadByteAt(struct BlockBuffer *buffer, uint16_t idx, uint8_t *outValue); + +/* + * @brief read a short value from buffer and move cursor to next. + * + * @param[in] buff the instance of gdk buffer. + * @param[in] ulOffset the offset from current cursor. + * + * @return the short value that read from buffer. + */ +bool HdfBlockBufferReadShort(struct BlockBuffer *buffer, uint16_t *value16); + +/* + * @brief read a short value from buffer and move cursor to next. + * + * @param[in] buff the instance of gdk buffer. + * @param[in] ulOffset the offset from current cursor. + * + * @return the short value that read from buffer. + */ +bool HdfBlockBufferReadShortAt(struct BlockBuffer *buffer, size_t idx, uint16_t *outValue); + +uint8_t *HdfBlockBufferGetData(struct BlockBuffer *buffer); + +/* + * @brief put a short value into buffer order with big endian. + * + * @param[in] buff the instance of gdk buffer. + * @param[in] short_value the short value that insert into buffer.. + * + * @return true if uint8 was write successfully, otherwise false. + */ +bool HdfBlockBufferWriteShort(struct BlockBuffer *buffer, uint16_t shortValue); + +/* + * @brief get buffer space size. + * + * @param[in] buff the instance of gdk buffer. + * @param[in] start the start index of duplicate buffer rang. + * @param[in] end the end index of duplicate buffer rang. + * + * @return the new instance of buff which contain specific packet. + */ +struct HdfBlockBuffer *HdfBlockBufferDuplicate( + struct HdfBlockBuffer *buffer, uint16_t start, uint16_t end); + +/* + * @brief append an byte array packet into buffer. + * + * @param[in] buff the instance of gdk buffer. + * @param[in] data the start address of byte array. + * @param[in] length the length of byte array. + * + * @return void + */ +void HdfBlockBufferRewind(struct HdfBlockBuffer *buffer); + +/* + * @brief put a byte into buffer. + * + * @param[in] buff -the instance of gdk buffer. + * @param[in] value -the byte value that insert into buffer.. + * + * @return true if uint8 was write successfully, otherwise false. + */ +bool HdfBlockBufferPutc(struct HdfBlockBuffer *buffer, uint8_t value); + +/* + * @brief append an byte array packet into buffer. + * + * @param[in] buff the instance of gdk buffer. + * @param[in] data the start address of byte array. + * @param[in] length the length of byte array. + * + * @return true if operation is success, otherwise false. + */ +bool HdfBlockBufferWriteData(struct HdfBlockBuffer *buffer, uint8_t *data, size_t length); + +bool HdfBlockBufferWriteBuff(struct HdfBlockBuffer *dst, struct HdfBlockBuffer *src); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* BLOCK_BUFFER_H */ diff --git a/utils/include/hdf_blocking_queue.h b/utils/include/hdf_blocking_queue.h new file mode 100644 index 0000000000000000000000000000000000000000..5cfda6ecdd941404fe10f3511e1656a5a98cbcb9 --- /dev/null +++ b/utils/include/hdf_blocking_queue.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2021-2021 Huawei Device Co., Ltd. + * + * HDF is dual licensed: you can use it either under the terms of + * the GPL, or the BSD license, at your option. + * See the LICENSE file in the root of this repository for complete details. + */ + +#ifndef BLOCKING_QUEUE_H +#define BLOCKING_QUEUE_H + +#include "hdf_slist.h" +#include "osal_sem.h" +#include "osal_mutex.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct HdfBlockingQueue +{ + struct HdfSList list; + struct OsalSem sem; + struct OsalMutex mutex; +}; + +struct HdfSListEntry +{ + struct HdfSListNode node; + void *data; +}; + +void HdfBlockingQueue_Init(struct HdfBlockingQueue *queue); + +void HdfBlockingQueueDestroy(struct HdfBlockingQueue *queue); + +void HdfBlockingQueueFlush(struct HdfBlockingQueue *queue); + +void *HdfBlockingQueueTake(struct HdfBlockingQueue *queue); + +void *HdfBlockingQueueGet(struct HdfBlockingQueue *queue); + +void HdfBlockingQueueRemove(struct HdfBlockingQueue *queue, void *data); + +void *HdfBlockingQueuePoll(struct HdfBlockingQueue *queue, long timeout); + +void HdfBlockingQueueOffer(struct HdfBlockingQueue *queue, void *val); + +void *HdfBlockingQueueFind(struct HdfBlockingQueue *queue, long match_key, SlList_Comparer comparer); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* BLOCKING_QUEUE_H */ diff --git a/utils/include/hdf_object_alloc.h b/utils/include/hdf_object_alloc.h new file mode 100644 index 0000000000000000000000000000000000000000..bfc6d6d4553ce01adaef6caf6891fffff24a3ea4 --- /dev/null +++ b/utils/include/hdf_object_alloc.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2021-2021 Huawei Device Co., Ltd. + * + * HDF is dual licensed: you can use it either under the terms of + * the GPL, or the BSD license, at your option. + * See the LICENSE file in the root of this repository for complete details. + */ + +#ifndef OBJECT_ALLOC_H +#define OBJECT_ALLOC_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct HdfObjectChunkConfig { + uint32_t chunkSize; + uint32_t chunkCount; +}; + +struct HdfObjectPoolConfig { + char *buffer; + uint32_t bufferSize; + uint32_t numChunks; + const struct HdfObjectChunkConfig *chunks; +}; + +void *HdfObjectAllocAlloc(size_t size); + +void HdfObjectAllocFree(void *object); + +const struct HdfObjectPoolConfig *ObjectAllocGetConfig(void); +void HdfObjectAllocInit(); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* BLOCK_BUFFER_H */ + diff --git a/utils/include/hdf_ordered_list.h b/utils/include/hdf_ordered_list.h new file mode 100644 index 0000000000000000000000000000000000000000..ffb4ad02d4e477011e0f96ca04f4c024a3a282d7 --- /dev/null +++ b/utils/include/hdf_ordered_list.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2021-2021 Huawei Device Co., Ltd. + * + * HDF is dual licensed: you can use it either under the terms of + * the GPL, or the BSD license, at your option. + * See the LICENSE file in the root of this repository for complete details. + */ + +#ifndef HDF_ORDERED_LIST_H +#define HDF_ORDERED_LIST_H + +#include "hdf_slist.h" +#include "osal_mutex.h" +#include "osal_sem.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct HdfOrderedList { + struct HdfSList head; + struct OsalSem sem; + struct OsalMutex mutex; +}; + +struct HdfOrderedListEntity { + struct HdfSListNode node; + long key; +}; + +typedef void(*HdfOrderedListEntityDeleter)(struct HdfOrderedListEntity *); + +typedef bool (*HdfOrderedListComparer)(long , void *); + +void HdfOrderedListInit(struct HdfOrderedList *list); + +void HdfOrderedListDestroy(struct HdfOrderedList *list); + +int HdfOrderedListIsEmpty(struct HdfOrderedList *list); + +void HdfOrderedListOffer(struct HdfOrderedList *list, struct HdfOrderedListEntity *newEntity); + +struct HdfOrderedListEntity *HdfOrderedListTake(struct HdfOrderedList *list); + +struct HdfOrderedListEntity *HdfOrderedListFetch( + struct HdfOrderedList *list, long match_key, HdfOrderedListComparer comparer); + +int HdfOrderedListWait(struct HdfOrderedList *list, long timeout); + +long HdfOrderedListPeekKey(struct HdfOrderedList *list); + +void HdfOrderedListFlush(struct HdfOrderedList *list, HdfOrderedListEntityDeleter deleter); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* HDF_ORDERED_LIST_H */ diff --git a/utils/src/hdf_block_buffer.c b/utils/src/hdf_block_buffer.c new file mode 100644 index 0000000000000000000000000000000000000000..7816114ed79aab289fa5d1134c1b7790dda94eed --- /dev/null +++ b/utils/src/hdf_block_buffer.c @@ -0,0 +1,214 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * + * HDF is dual licensed: you can use it either under the terms of + * the GPL, or the BSD license, at your option. + * See the LICENSE file in the root of this repository for complete details. + */ + +#include +#include +#include "hdf_block_buffer.h" +#include "osal_mem.h" +#include "utils.h" + +struct HdfHdfBlockBuffer *HdfHdfBlockBufferNew(const uint8_t *data, uint16_t size) +{ + uint16_t wantedSize; + struct HdfBlockBuffer *buffer = NULL; + if (size == 0) { + return NULL; + } + wantedSize = sizeof(struct HdfBlockBuffer) + size; + buffer = (struct HdfBlockBuffer *)OsalMemAlloc(wantedSize); + if (buffer == NULL) { + return NULL; + } + buffer->dataSize = size; + buffer->position = 0; + if (data != NULL) { + memcpy(buffer->data, data, size); + } + return buffer; +} + +void HdfBlockBufferFree(struct HdfBlockBuffer *buffer) +{ + if (buffer != NULL) { + free(buffer); + } +} + +uint16_t HdfBlockBufferGetDataSize(struct HdfBlockBuffer *buffer) +{ + return (buffer == NULL) ? 0 : buffer->dataSize; +} + +uint16_t HdfBlockBufferGetAvailableSize(struct HdfBlockBuffer *buffer) +{ + return (buffer == NULL) ? 0 : buffer->dataSize - buffer->position; +} + +uint8_t *HdfBlockBufferRead(struct HdfBlockBuffer *buffer, uint16_t size) +{ + uint8_t *dataPtr = NULL; + if ((buffer == NULL) || (buffer->dataSize - buffer->position < size)) { + return NULL; + } + dataPtr = &buffer->data[buffer->position]; + buffer->position += size; + return dataPtr; +} + +uint8_t *HdfBlockBufferGetData(struct HdfBlockBuffer *buffer) +{ + return (buffer == NULL) ? NULL : &buffer->data[0]; +} + +uint16_t HdfBlockBufferGetPoistion(struct HdfBlockBuffer *buffer) +{ + return (buffer == NULL) ? 0 : buffer->position; +} + + +uint16_t HdfBlockBufferSkipBytes(struct HdfBlockBuffer *buffer, uint16_t bytes) +{ + if (buffer == NULL) { + return 0; + } + if (buffer->position + bytes <= buffer->dataSize) { + buffer->position += bytes; + return buffer->dataSize - buffer->position; + } else { + buffer->position = buffer->dataSize; + return 0; + } +} + +bool HdfBlockBufferReadUint8(struct HdfBlockBuffer *buffer, uint8_t *outValue) +{ + if (buffer == NULL) { + return false; + } + if (buffer->position + BYTES_UINT8 <= buffer->dataSize) { + *outValue = buffer->data[buffer->position++]; + return true; + } + return false; +} + +bool HdfBlockBufferReadUint8At(struct HdfBlockBuffer *buffer, uint16_t idx, uint8_t *outValue) +{ + if (buffer == NULL) { + return false; + } + if (idx + BYTES_UINT8 <= buffer->dataSize) { + *outValue = buffer->data[idx]; + return true; + } + return false; +} + +bool HdfBlockBufferReadUint16(struct HdfBlockBuffer *buffer, uint16_t *outValue) +{ + if (buffer == NULL) { + return false; + } + if (buffer->position + BYTES_UINT16 <= buffer->dataSize) { + *outValue = read_be16(buffer->data, buffer->position); + buffer->position += BYTES_UINT16; + return true; + } + return false; +} + +bool HdfBlockBufferReadUint16At(struct HdfBlockBuffer *buffer, size_t idx, uint16_t *outValue) +{ + if (buffer == NULL) { + return false; + } + if (idx + BYTES_UINT16 <= buffer->dataSize) { + *outValue = read_be16(buffer->data, idx); + return true; + } + return false; +} + +void HdfBlockBufferRewind(struct HdfBlockBuffer *buffer) +{ + if (buffer != NULL) { + buffer->position = 0; + } +} + +bool HdfBlockBufferWriteUint8(struct HdfBlockBuffer *buffer, uint8_t value) +{ + if (buffer == NULL) { + return false; + } + if (buffer->position + sizeof(uint8_t) <= buffer->dataSize) { + buffer->data[buffer->position++] = value; + return true; + } + return false; +} + +bool HdfBlockBufferWriteUint16(struct HdfBlockBuffer *buffer, uint16_t in_value) +{ + if (buffer == NULL) { + return false; + } + if (buffer->position + BYTES_UINT16 <= buffer->dataSize) { + buffer->data[buffer->position++] = (uint8_t) (in_value >> 8); + buffer->data[buffer->position++] = (uint8_t) (in_value & 0xFF); + return true; + } + return false; +} + +bool HdfBlockBufferWriteData(struct HdfBlockBuffer *buffer, uint8_t *data, size_t length) +{ + uint16_t residualSize; + if (buffer == NULL) { + return false; + } + residualSize = buffer->dataSize - buffer->position; + if (length > residualSize) { + return false; + } + memcpy(buffer->data + buffer->position, data, length); + buffer->position += length; + return true; +} + +struct HdfBlockBuffer *HdfBlockBufferDuplicate( + struct HdfBlockBuffer *buffer, uint16_t start, uint16_t end) +{ + uint16_t bufferSize = HdfBlockBufferGetDataSize(buffer); + uint16_t newBufferSize; + struct HdfBlockBuffer *newBuffer = NULL; + if ((buffer == NULL) || (start > end)) { + return NULL; + } + if ((end > bufferSize) || (start > bufferSize)) { + return NULL; + } + newBufferSize = end - start + 1; + newBuffer = HdfBlockBufferNew(newBufferSize); + if (newBuffer == NULL) { + return NULL; + } + memcpy(newBuffer->data, buffer->data + start, newBufferSize); + return newBuffer; +} + +bool HdfBlockBufferWriteBuff(struct HdfBlockBuffer *dst, struct HdfBlockBuffer *src) +{ + if (dst->position + src->dataSize <= dst->dataSize) { + memcpy(&dst->data[dst->position], src->data, src->dataSize); + dst->position += src->dataSize; + return true; + } + return false; +} + diff --git a/utils/src/hdf_blocking_queue.c b/utils/src/hdf_blocking_queue.c new file mode 100644 index 0000000000000000000000000000000000000000..613849e9ede996df8a586b31602f81a48883ab53 --- /dev/null +++ b/utils/src/hdf_blocking_queue.c @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2021-2021 Huawei Device Co., Ltd. + * + * HDF is dual licensed: you can use it either under the terms of + * the GPL, or the BSD license, at your option. + * See the LICENSE file in the root of this repository for complete details. + */ + +#include "blocking_queue.h" + +void HdfBlockingQueueInit(struct HdfBlockingQueue *queue) +{ + HdfSListInit(&queue->list); + OsalSemInit(&queue->sem); + OsalMutexInit(&queue->mutex); +} + +void HdfBlockingQueueDestroy(struct HdfBlockingQueue *queue) +{ + HdfSListInit(&queue->list); + OsalSemDestroy(&queue->sem); + OsalMutexDestroy(&queue->mutex); +} + +void HdfBlockingQueueFlush(struct HdfBlockingQueue *queue) +{ + OsalMutexLock(&queue->mutex); + HdfSListFlush(&queue->list, HdfSListRemove); + OsalMutexUnlock(&queue->mutex); + OsalSemPost(&queue->sem); +} + +void *HdfBlockingQueueTake(struct HdfBlockingQueue *queue) +{ + void *data = HdfBlockingQueueGet(queue); + if (data == NULL) { + OsalSemWait(&queue->sem, OSAL_WAIT_FOREVER); + data = HdfBlockingQueueGet(queue); + } + return data; +} + +void *HdfBlockingQueueGet(struct HdfBlockingQueue *queue) +{ + void *data = NULL; + struct HdfSListEntry *entry; + OsalMutexLock(&queue->mutex); + entry = (struct HdfSListEntry *)HdfSListPeek(&queue->list); + OsalMutexUnlock(&queue->mutex); + if (entry != NULL) { + data = entry->data; + HdfSListEntryFree(entry); + } + return data; +} + + +void *HdfBlockingQueueFind(struct HdfBlockingQueue *queue, long matchKey, SlList_Comparer comparer) +{ + void *matchData = NULL; + struct HdfSListIterator it; + struct HdfSListEntry *entry = NULL; + if (comparer == NULL) { + return NULL; + } + OsalMutexLock(&queue->mutex); + HdfSListIteratorInit(&it, &queue->list); + while (HdfSListIteratorHasNext(&it)) { + entry = (struct HdfSListEntry *) HdfSListIteratorNext(&it); + if (comparer(matchKey, entry->data)) { + matchData = entry->data; + break; + } + } + OsalMutexUnlock(&queue->mutex); + return matchData; +} + +void HdfBlockingQueueRemove(struct HdfBlockingQueue *queue, void *data) +{ + bool targetListChanged = false; + struct HdfSListIterator it; + struct HdfSListEntry *entry = NULL; + OsalMutexLock(&queue->mutex); + HdfSListIteratorInit(&it, &queue->list); + while (HdfSListIteratorHasNext(&it)) { + entry = (struct HdfSListEntry *)HdfSListIteratorNext(&it); + if (entry->data == data) { + HdfSListIteratorRemove(&it); + HdfSListEntryFree(entry); + targetListChanged = true; + break; + } + } + OsalMutexUnlock(&queue->mutex); + if (targetListChanged) { + OsalSemPost(&queue->sem); + } +} + +void *HdfBlockingQueuePoll(struct HdfBlockingQueue *queue, long timeout) +{ + void *data = HdfBlockingQueueGet(queue); + if (data == NULL) { + OsalSemWait(&queue->sem, timeout); + data = HdfBlockingQueueGet(queue); + } + return data; +} + +int HdfBlockingQueueOffer(struct HdfBlockingQueue *queue, void *val, long timeout) +{ + struct HdfSListEntry *entry = NULL; + if (OsalSemWait(&queue->sem, timeout) != 0) { + return -1; + } + entry = HdfSListEntryNew(val); + if (entry != NULL) { + OsalMutexLock(&queue->mutex); + HdfSListAddTail(&queue->list, &entry->node); + OsalMutexUnlock(&queue->mutex); + } + OsalSemPost(&queue->sem); +} + diff --git a/utils/src/hdf_object_alloc.c b/utils/src/hdf_object_alloc.c new file mode 100644 index 0000000000000000000000000000000000000000..ba4774c751d175d0f43608ada1582d43802784a4 --- /dev/null +++ b/utils/src/hdf_object_alloc.c @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * + * HDF is dual licensed: you can use it either under the terms of + * the GPL, or the BSD license, at your option. + * See the LICENSE file in the root of this repository for complete details. + */ + +#include +#include + +#include "hdf_slist.h" +#include "object_alloc.h" +#include "osal_mem.h" +#include "osal_mutex.h" +#include "utils.h" + +struct HdfChunkLink { + uint32_t buffSize; + uint8_t *buffer; +}; + +struct HdfObjectNode { + struct HdfSListNode entry; + uint32_t chunkCount; + uint32_t freeCount; + uint32_t chunkSize; + struct HdfChunkLink **chunkStack; +}; + +struct HdfObjectAlloc { + struct HdfSList nodes; + struct OsalMutex mutex; + bool isConstructed; +}; +static const unsigned int ALIGN_MASK = 3; +#define ALIGN4(x) (uint32_t)(((uintptr_t)(x) + ALIGN_MASK) & (~ALIGN_MASK)) + +#define OBJECT_NODE_SIZE sizeof(struct ObjectNode) +#define OBJECT_CHUNK_COOKIE_SIZE (sizeof(struct ChunkLink) + sizeof(void *)) + +void HdfObjectAllocConstruct(struct HdfObjectAlloc *alloc) +{ + HdfSListInit(&alloc->nodes); + OsalMutexInit(&alloc->mutex); + alloc->isConstructed = true; +} +struct HdfObjectAlloc *HdfObjectAllocGetInstance() +{ + static struct HdfObjectAlloc instance = { 0 }; + + if (!instance.isConstructed) { + HdfObjectAllocConstruct(&instance); + } + + return &instance; +} + +struct HdfObjectNode *HdfObjectAllocFindSuitableChunk( + struct HdfObjectAlloc *alloc, size_t size) +{ + struct HdfSListIterator it; + struct HdfObjectNode *bestFitNode = NULL; + struct HdfObjectNode *objectNode = NULL; + HdfSListIteratorInit(&it, &alloc->nodes); + + while (HdfSListIteratorHasNext(&it)) { + objectNode = (struct HdfObjectNode *)HdfSListIteratorNext(&it); + + if (size == objectNode->chunkSize) { + bestFitNode = objectNode; + break; + } else if (size < objectNode->chunkSize) { + bestFitNode = objectNode; + } + } + + return bestFitNode; +} + +static void HdfObjectAllocPushObjectNode( + struct HdfObjectAlloc *alloc, struct HdfObjectNode *node) +{ + struct HdfSListIterator it; + struct HdfObjectNode *objectNode = NULL; + HdfSListIteratorInit(&it, &alloc->nodes); + + while (HdfSListIteratorHasNext(&it)) { + objectNode = (struct HdfObjectNode *)HdfSListIteratorNext(&it); + + if (node->chunkSize >= objectNode->chunkSize) { + break; + } + } + + HdfSListIteratorInsert(&it, &node->entry); +} + +static void HdfObjectAllocPreloadChunk( + void *chunkBuf, uint32_t buffSize, uint32_t chunkSize) +{ + struct HdfObjectAlloc *allocator = HdfObjectAllocGetInstance(); + + if (buffSize > OBJECT_NODE_SIZE) { + uint32_t idx; + struct ChunkLink *chunkLink; + struct ObjectNode *node; + uint32_t alignedSize = ALIGN4(chunkSize); + uint32_t alignedBufSize = ALIGN4(buffSize); + uint32_t blockSize = alignedSize + sizeof(struct ChunkLink); + uint8_t *alignedBuff = (uint8_t *)(uintptr_t)ALIGN4(chunkBuf); + node = (struct ObjectNode *)(alignedBuff + alignedBufSize - OBJECT_NODE_SIZE); + node->freeCount = 0; + node->chunkSize = alignedSize; + node->chunkCount = ((uint8_t *)node - alignedBuff) / (blockSize + sizeof(void *)); + node->chunkStack = (struct ChunkLink **)(alignedBuff + node->chunkCount * blockSize); + + for (idx = 0; idx < node->chunkCount; idx++) { + chunkLink = (struct ChunkLink *)&alignedBuff[idx * blockSize]; + chunkLink->buffSize = node->chunkSize; + node->chunkStack[node->freeCount++] = chunkLink; + chunkLink->buffer = (uint8_t *)(chunkLink + 1); + } + + HdfObjectAllocPushObjectNode(allocator, node); + } +} + +void HdfObjectAllocLoadConfigs(const struct HdfObjectPoolConfig *configs) +{ + uint32_t idx = 0; + char *chunkBuffBegin = configs->buffer; + char *chunkBuffEnd = configs->buffer + configs->bufferSize; + + for (idx = 0; (idx < configs->numChunks) && (chunkBuffBegin < chunkBuffEnd); idx++) { + const struct ObjectChunkConfig *chunkConfig = &configs->chunks[idx]; + size_t chunkBufSize = OBJECT_NODE_SIZE + \ + (OBJECT_CHUNK_COOKIE_SIZE + chunkConfig->chunkSize) * chunkConfig->chunkCount; + + if (chunkBuffBegin + chunkBufSize <= chunkBuffEnd) { + HdfObjectAllocPreloadChunk(chunkBuffBegin, chunkBufSize, chunkConfig->chunkSize); + } + + chunkBuffBegin += chunkBufSize; + } +} + +void HdfObjectAllocInit() +{ + const struct HdfObjectPoolConfig *config = HdfObjectAllocGetConfig(); + + if (config != NULL) { + HdfObjectAllocLoadConfigs(config); + } +} + +void *HdfObjectAllocAlloc(size_t size) +{ + struct HdfChunkLink *chunkLink = NULL; + struct HdfObjectNode *objectNode = NULL; + struct HdfObjectAlloc *allocator = HdfObjectAllocGetInstance(); + OsalMutexLock(&allocator->mutex); + objectNode = HdfObjectAllocFindSuitableChunk(allocator, size); + + if ((objectNode != NULL) && (objectNode->freeCount == 0)) { + goto finished; + } + + if (objectNode->freeCount > objectNode->chunkCount) { + if (objectNode->freeCount > objectNode->chunkCount) { + } + } + + chunkLink = (struct ChunkLink *)objectNode->chunkStack[--objectNode->freeCount]; +finished: + OsalMutexUnlock(&allocator->mutex); + return chunkLink ? chunkLink->buffer : NULL; +} + +void HdfObjectAllocFree(void *object) +{ + struct HdfChunkLink *chunkLink = container_of(void, object, struct ChunkLink, buffer); + struct HdfObjectNode *objectNode = NULL; + struct HdfObjectAlloc *allocator = HdfObjectAllocGetInstance(); + OsalMutexLock(&allocator->mutex); + objectNode = HdfObjectAllocFindSuitableChunk(allocator, chunkLink->buffSize); + + if (objectNode != NULL) { + objectNode->chunkStack[objectNode->freeCount++] = chunkLink; + + if (objectNode->freeCount > objectNode->chunkCount) { + HDF_LOGE("exception: count,free:%d,total %d", objectNode->freeCount, objectNode->chunkCount); + } + } + + OsalMutexUnlock(&allocator->mutex); +} + diff --git a/utils/src/hdf_ordered_list.c b/utils/src/hdf_ordered_list.c new file mode 100644 index 0000000000000000000000000000000000000000..a3cc2e2b94e60d823584a58392d03712a288c7f8 --- /dev/null +++ b/utils/src/hdf_ordered_list.c @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * + * HDF is dual licensed: you can use it either under the terms of + * the GPL, or the BSD license, at your option. + * See the LICENSE file in the root of this repository for complete details. + */ + +#include "osal_mem.h" +#include "hdf_ordered_list.h" + +void HdfOrderedListInit(struct HdfOrderedList *list) +{ + OsalMutexInit(&list->mutex); + OsalSemInit(&list->sem); + HdfSListInit(&list->head); +} + +void HdfOrderedListDestroy(struct HdfOrderedList *list) +{ + HdfSListInit(&list->head); + OsalSemDestroy(&list->sem); + OsalMutexDestroy(&list->mutex); +} + +int HdfOrderedListIsEmpty(struct HdfOrderedList *list) +{ + return HdfSListIsEmpty(&list->head); +} + +void HdfOrderedListOffer(struct HdfOrderedList *list, struct HdfOrderedListEntity *newEntity) +{ + struct HdfSListIterator it; + struct HdfOrderedListEntity *matchEntity; + if ((list == NULL) || (newEntity == NULL)) { + return; + } + OsalMutexLock(&list->mutex); + if (HdfSListIsEmpty(&list->head)) { + HdfSListAdd(&list->head, &newEntity->node); + goto finished; + } + HdfSListIteratorInit(&it, &list->head); + while (HdfSListIteratorHasNext(&it)) { + matchEntity = (struct HdfOrderedListEntity *)HdfSListIteratorNext(&it); + if (newEntity->key > matchEntity->key) { + HdfSListIteratorInsert(&it, &newEntity->node); + break; + } + } +finished: + OsalMutexUnlock(&list->mutex); + OsalSemPost(&list->sem); +} + +struct HdfOrderedListEntity *HdfOrderedListGet(struct HdfOrderedList *list) +{ + struct HdfOrderedListEntity *entity; + OsalMutexLock(&list->mutex); + entity = (struct HdfOrderedListEntity *)HdfSListPeek(&list->head); + OsalMutexUnlock(&list->mutex); + return entity; +} + +struct HdfOrderedListEntity *HdfOrderedListTake(struct HdfOrderedList *list) +{ + struct HdfOrderedListEntity *entity = HdfOrderedListGet(list); + while (entity == NULL) { + OsalSemWait(&list->sem, OSAL_WAIT_FOREVER); + entity = HdfOrderedListGet(list); + } + return entity; +} + +long HdfOrderedListPeekKey(struct HdfOrderedList *list) +{ + long orderedKey = 0; + struct HdfOrderedListEntity *firstEntity; + OsalMutexLock(&list->mutex); + firstEntity = (struct HdfOrderedListEntity *)HdfSListPeek(&list->head); + if (firstEntity != NULL) { + orderedKey = firstEntity->key; + } + OsalMutexUnlock(&list->mutex); + return orderedKey; +} + +struct HdfOrderedListEntity *HdfOrderedListFetch( + struct HdfOrderedList *list, long matchKey, HdfOrderedListComparer comparer) +{ + struct HdfSListIterator it; + struct HdfOrderedListEntity *matchEntity = NULL; + if (comparer == NULL) { + return matchEntity; + } + OsalMutexLock(&list->mutex); + HdfSListIteratorInit(&it, &list->head); + while (HdfSListIteratorHasNext(&it)) { + struct OrderedListEntity *searchEntity = + (struct OrderedListEntity *)HdfSListIteratorNext(&it); + if (comparer(matchKey, searchEntity)) { + HdfSListIteratorRemove(&it); + matchEntity = searchEntity; + break; + } + } + OsalMutexUnlock(&list->mutex); + return matchEntity; +} + +void HdfOrderedListFlush(struct HdfOrderedList *list, HdfOrderedListEntityDeleter deleter) +{ + OsalMutexLock(&list->mutex); + HdfSListFlush(&list->head, (HdfSListDeleter)deleter); + OsalMutexUnlock(&list->mutex); + OsalSemPost(&list->sem); +} + +int HdfOrderedListWait(struct HdfOrderedList *list, long timeout) +{ + OsalSemWait(&list->sem, timeout); +}