mirror of
https://github.com/openharmony/drivers_framework.git
synced 2026-07-21 03:35:25 -04:00
add hdf util function
Signed-off-by: wangchangliang21 <austin.wang@huawei.com>
This commit is contained in:
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
Reference in New Issue
Block a user