* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FILLP_QUEUE_H
#define FILLP_QUEUE_H
#include "lf_ring.h"
#include "spunge_mem.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct InnerfillpQueue {
FILLP_INT allocType;
#ifdef FILLP_64BIT_ALIGN
FILLP_UINT8 padd[4];
#endif
size_t size;
struct FillpLfRing ring;
} FillpQueue;
static __inline FillpErrorType FillpQueuePush(FillpQueue *q, void **msg, FILLP_INT isTryPush, FILLP_UINT count)
{
FILLP_INT ret;
FILLP_INT totalPush = 0;
for (;;) {
ret = FillpLfRingMpEnqueue(&q->ring, &msg[totalPush], count - (FILLP_UINT)totalPush);
if (ret > 0) {
totalPush += ret;
if ((FILLP_UINT)totalPush == count) {
return ERR_OK;
}
} else if (isTryPush) {
return ERR_NOBUFS;
}
}
}
static __inline FILLP_INT FillpQueuePop(FillpQueue *q, void **msg, FILLP_UINT count)
{
if ((q == FILLP_NULL_PTR) || (msg == FILLP_NULL_PTR)) {
return -1;
}
return FillpLfRingMcDequeue(&q->ring, msg, count);
}
static __inline int QueueEmpty(FILLP_CONST FillpQueue *q)
{
return FillpRingEmpty(&q->ring);
}
static __inline size_t FillpQueueCalMemSize(size_t size)
{
size_t tmpSize = FillpLfRingCalMemSize(size);
size_t memSize = tmpSize + sizeof(FillpQueue);
if ((tmpSize == 0) || (memSize < sizeof(FillpQueue))) {
return 0;
}
return memSize;
}
static __inline void FillpQueueSetProdSafe(FillpQueue *q, FILLP_BOOL safe)
{
FillpLfRingSetProdSafe(&q->ring, safe);
}
static __inline void FillpQueueSetConsSafe(FillpQueue *q, FILLP_BOOL safe)
{
FillpLfRingSetConsSafe(&q->ring, safe);
}
static __inline void FillpQueueInit(FillpQueue *q, char *name, size_t size, FILLP_INT allocType)
{
FillpLfRingInit(&q->ring, name, size);
q->allocType = allocType;
q->size = size;
}
static __inline FillpQueue *FillpQueueCreate(char *name, size_t size, FILLP_INT allocType)
{
FillpQueue *q;
q = (FillpQueue *)SpungeAlloc(1, FillpQueueCalMemSize(size), allocType);
if (q == FILLP_NULL_PTR) {
FILLP_LOGERR("Failed to allocate the memory for queue \r\n");
return FILLP_NULL_PTR;
}
FillpQueueInit(q, name, size, allocType);
return q;
}
static __inline void FillpQueueDestroy(FillpQueue *q)
{
if (q == FILLP_NULL_PTR) {
return;
}
if ((q->allocType == SPUNGE_ALLOC_TYPE_MALLOC) || (q->allocType == SPUNGE_ALLOC_TYPE_CALLOC)) {
SpungeFree(q, q->allocType);
}
}
static __inline FILLP_ULONG FillpQueueValidOnes(FillpQueue *q)
{
if (q == FILLP_NULL_PTR) {
return 0;
}
return FillpRingValidOnes(&q->ring);
}
#ifdef __cplusplus
}
#endif
#endif