diff options
Diffstat (limited to 'source/LCM/Queue.cpp')
-rw-r--r-- | source/LCM/Queue.cpp | 291 |
1 files changed, 291 insertions, 0 deletions
diff --git a/source/LCM/Queue.cpp b/source/LCM/Queue.cpp new file mode 100644 index 0000000..d2ef64e --- /dev/null +++ b/source/LCM/Queue.cpp @@ -0,0 +1,291 @@ +/******************************************************************************* + * Copyright (C) ST-Ericsson SA 2011 + * License terms: 3-clause BSD license + ******************************************************************************/ +/* + * @addtogroup ldr_utilities + * @{ + * @addtogroup queue + * @{ + */ + +/******************************************************************************* + * Includes + ******************************************************************************/ +#include "Queue.h" +#include "LCDriverMethods.h" +#include <cstdlib> +#include <cstring> + +/******************************************************************************* + * Types, constants + ******************************************************************************/ + +typedef struct Queue_s { + /* Head index of the buffer. This is where items are inserted.*/ + uint32 Head; + /* Tail index of the buffer. This is where items are removed.*/ + uint32 Tail; + /* Size of the buffer.*/ + uint32 Size; + /* Buffer pointer.*/ + void **Buffer_pp; + /* Empty buffer callback pointer. */ + void (*EmptyCallback)(const void *const Queue_p, void *Param_p); + /* The parameter is used for the empty buffer transition callback.*/ + void *EmptyParam_p; + /* NonEmpty buffer callback pointer. */ + void (*NonEmptyCallback)(const void *const Queue_p, void *Param_p); + /* The parameter used for the non-empty buffer transition callback.*/ + void *NonEmptyParam_p; + /* Pointer to a function for deallocating any resources that are reserved for + * the element. This function is provided as an input parameter when the queue + * is created. + */ + void (*DestroyElement)(void *Value_p); +} Queue_t; + +Queue::Queue(void) +{ + logger_ = NULL; +} + +Queue::~Queue(void) +{ +} + +/******************************************************************************* + * Definition of external functions + ******************************************************************************/ +void Queue::Create(void **const Queue_pp, const uint32 MaxLength, void (*DestroyElement)(void *Element_p)) +{ + Queue_t *Queue_p = new Queue_t; + + if (Queue_p != 0) { + Queue_p->Size = MaxLength; + Queue_p->Head = 0; + Queue_p->Tail = 0; + Queue_p->Buffer_pp = new void*[MaxLength + 1]; + Queue_p->DestroyElement = DestroyElement; + Queue_p->NonEmptyCallback = 0; + Queue_p->NonEmptyParam_p = 0; + Queue_p->EmptyCallback = 0; + Queue_p->EmptyParam_p = 0; + + *Queue_pp = Queue_p; + +#ifdef _QUEUEDEBUG + PrintF("Queue: Create - Queue 0x%p", Queue_p); +#endif + } else { +#ifdef _QUEUEDEBUG + PrintF("Queue: Create - Not enough memory Queue 0x%p", 0); +#endif + } +} + +void Queue::Destroy(void **const Queue_pp) +{ + Queue_t *Queue_p = (Queue_t *) * Queue_pp; + void *Object_p = 0; + + if (NULL != Queue_p->DestroyElement) { + Object_p = Dequeue(Queue_p); + + while (0 != Object_p) { + Queue_p->DestroyElement(Object_p); + Object_p = Dequeue(Queue_p); + } + } + +#ifdef _QUEUEDEBUG + PrintF("Queue: Destroy - Queue 0x%p", Queue_p); +#endif + + delete[] Queue_p->Buffer_pp; + delete Queue_p; + *Queue_pp = NULL; +} + +ErrorCode_e Queue::Enqueue(void *const Queue_p, void *const Object_p) +{ + Queue_t *TempQueue_p = (Queue_t *)Queue_p; + uint32 Head = (TempQueue_p->Head + 1) % TempQueue_p->Size; + boolean NonEmptyCall = (TempQueue_p->Head == TempQueue_p->Tail); + + if (Head != TempQueue_p->Tail) { +#ifdef _QUEUEDEBUG + PrintF("Queue: Enqueue - Queue 0x%p", Queue_p); + PrintF("Queue: Enqueue - Object 0x%p", Object_p); +#endif + TempQueue_p->Buffer_pp[Head] = Object_p; + TempQueue_p->Head = Head; + + if (Head == TempQueue_p->Tail) { +#ifdef _QUEUEDEBUG + PrintF("Queue: Enqueue - return E_FAILED_TO_STORE_IN_FIFO, Object 0x%p", Object_p); +#endif + return E_FAILED_TO_STORE_IN_FIFO; + } + + if (NonEmptyCall && NULL != TempQueue_p->NonEmptyCallback) { +#ifdef _QUEUEDEBUG + PrintF("Queue: Enqueue - Executing NonEmptyCallback Queue 0x%p", Queue_p); +#endif + TempQueue_p->NonEmptyCallback(TempQueue_p, TempQueue_p->NonEmptyParam_p); + } + + return E_SUCCESS; + } else { +#ifdef _QUEUEDEBUG + PrintF("Queue: Enqueue - return E_FAILED_TO_STORE_IN_FIFO, Object 0x%p", Object_p); +#endif + return E_FAILED_TO_STORE_IN_FIFO; + } +} + +void *Queue::Dequeue(void *const Queue_p) +{ + Queue_t *TempQueue_p = (Queue_t *)Queue_p; + uint32 Tail = TempQueue_p->Tail; + void *Object_p = NULL; + + if (Tail != TempQueue_p->Head) { +#ifdef _QUEUEDEBUG + PrintF("Queue: Dequeue - Queue 0x%p", Queue_p); +#endif + Tail = (Tail + 1) % TempQueue_p->Size; + Object_p = TempQueue_p->Buffer_pp[Tail]; + TempQueue_p->Tail = Tail; + + if (Tail == TempQueue_p->Head && NULL != TempQueue_p->EmptyCallback) { +#ifdef _QUEUEDEBUG + PrintF("Queue: Dequeue - Executing EmptyCallback Queue 0x%p", Queue_p); +#endif + TempQueue_p->EmptyCallback(TempQueue_p, TempQueue_p->EmptyParam_p); + } + +#ifdef _QUEUEDEBUG + PrintF("Queue: Dequeue - Object 0x%p", Object_p); +#endif + } + + return Object_p; +} + +QueueCallback_fn Queue::SetCallback(void *const Queue_p, + const QueueCallbackType_e Type, + const QueueCallback_fn Callback, + void *const Param_p) +{ + Queue_t *TempQueue_p = (Queue_t *)Queue_p; + QueueCallback_fn OldCallback; + + if (Type == QUEUE_EMPTY) { + OldCallback = TempQueue_p->EmptyCallback; + TempQueue_p->EmptyCallback = Callback; + TempQueue_p->EmptyParam_p = Param_p; + } else { + OldCallback = TempQueue_p->NonEmptyCallback; + TempQueue_p->NonEmptyCallback = Callback; + TempQueue_p->NonEmptyParam_p = Param_p; + } + + return OldCallback; +} + +boolean Queue::IsEmpty(const void *const Queue_p) +{ + Queue_t *TempQueue_p = (Queue_t *)Queue_p; + + if (TempQueue_p->Tail == TempQueue_p->Head) { + return TRUE; + } else { + return FALSE; + } +} + +boolean Queue::IsMember(const void *const Queue_p, void *Value_p, boolean(*Match)(void *Value1_p, void *Value2_p)) +{ + Queue_t *TempQueue_p = (Queue_t *)Queue_p; + + for (size_t i = TempQueue_p->Head; i < TempQueue_p->Tail; i++) { + if (Match(Value_p, TempQueue_p->Buffer_pp[i])) { + return TRUE; + } + } + + return FALSE; +} + +int Queue::GetNrOfElements(const void *const Queue_p) +{ + Queue_t *TempQueue_p = (Queue_t *)Queue_p; + int Return = 0; + + if (TempQueue_p->Head >= TempQueue_p->Tail) { + Return = TempQueue_p->Head - TempQueue_p->Tail; + } else { + Return = TempQueue_p->Size - (TempQueue_p->Tail - TempQueue_p->Head); + } + + return Return; +} + +void Queue::RCreate(void **const Queue_pp, const uint32 MaxLength, void (*DestroyElement)(void *)) +{ + CLockCS QueueLock(QueueCSO); + Create(Queue_pp, MaxLength, DestroyElement); +} + +void Queue::RDestroy(void **const Queue_pp) +{ + CLockCS QueueLock(QueueCSO); + Destroy(Queue_pp); +} + +ErrorCode_e Queue::REnqueue(void *const Queue_p, void *const Value_p) +{ + CLockCS QueueLock(QueueCSO); + return Enqueue(Queue_p, Value_p); +} + +void *Queue::RDequeue(void *const Queue_p) +{ + CLockCS QueueLock(QueueCSO); + return Dequeue(Queue_p); +} + +QueueCallback_fn Queue::RSetCallback(void *const Queue_p, + const QueueCallbackType_e Type, + const QueueCallback_fn Callback, + void *const Param_p) +{ + CLockCS QueueLock(QueueCSO); + return SetCallback(Queue_p, Type, Callback, Param_p); +} + +boolean Queue::RIsEmpty(const void *const Queue_p) +{ + CLockCS QueueLock(QueueCSO); + return IsEmpty(Queue_p); +} + +boolean Queue::RIsMember(const void *const Queue_p, void *Value_p, boolean(*Match)(void *Value1_p, void *Value2_p)) +{ + CLockCS QueueLock(QueueCSO); + return IsMember(Queue_p, Value_p, Match); +} + +int Queue::RGetNrOfElements(const void *const Queue_p) +{ + CLockCS QueueLock(QueueCSO); + return GetNrOfElements(Queue_p); +} + +void Queue::PrintF(const char *text, void *pVoid) +{ + if (NULL != logger_) { + logger_->log(text, pVoid); + } +} |