add hdf util function

Signed-off-by: wangchangliang21 <austin.wang@huawei.com>
This commit is contained in:
wangchangliang21
2021-09-14 14:39:18 +08:00
parent 2ce8720c7a
commit c85b17efd8
8 changed files with 954 additions and 0 deletions
+140
View File
@@ -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 <stdio.h>
#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 */
+55
View File
@@ -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 */
+42
View File
@@ -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 <stdint.h>
#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 */
+58
View File
@@ -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 */
+214
View File
@@ -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 <stdlib.h>
#include <string.h>
#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;
}
+125
View File
@@ -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);
}
+198
View File
@@ -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 <stdint.h>
#include <stdio.h>
#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);
}
+122
View File
@@ -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);
}