//***************************************************************************** // (C) Automotive Lighting China // // Automotive Lighting Reutlingen GmbH owns all the rights to this work. // This work shall not be copied, reproduced, used, modified, transferred // or its information shall not be disclosed without the prior written // authorization of Automotive Lighting China. //***************************************************************************** // ---------------------------------------------------------------------------- /// \file StaticRingQueue.c /// /// \author f24301c [mailto:walker.lv@marelli.com] /// /// \date 05.27.2024 /// /// \brief StaticRingQueue API implementation /// // ---------------------------------------------------------------------------- //============================================================================= // Includes //============================================================================= #include "StaticRingQueue.h" #include #include #include #include //============================================================================= // Defines and Typedef //============================================================================= // NOTENOTE: missing memmap //----------------------------------------------------------------------------- // Start declaration or definitions of functions //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- /// \brief initialization a StaticRingQueue instance /// /// \descr Synchronous. setup necessary state of the queue /// /// \param pThis: pointer to the instance of StaticRingQueue /// /// \return UUE_ErrorType, UUE error type /// //----------------------------------------------------------------------------- UUE_ErrorType Queue_Init(StaticRingQueue_t* pThis) { UUE_ErrorType retVal = E_UUE_NO_ERROR; if (pThis == NULL_PTR) return E_UUE_BAD_PARAMETER; pThis->head = 0; pThis->tail = 0; //pThis->depth; // predefine in PBcfg.c pThis->level = 0; UUE_ASSERT(pThis->depth > 0); uint8 loops = pThis->depth; for (uint8 idx = 0; idx < loops; idx++) { //pThis->entities[idx].pdu = (ProtocolBuf_t*) NULL_PTR; ProtocolBuf_t* pdu = &pThis->entities[idx].pdu; memset(&pdu->tcb, 0, sizeof(pdu->tcb)); memset(pdu->reqPduBuffer, 0, sizeof(pdu->reqPduBuffer)); pdu->reqPduLength = 0; pdu->resPduBuffer = (uint8*)NULL_PTR; pdu->resPduLength = 0; pdu->transactionNotifyCallback = (transaction_notify_callback_t)NULL_PTR; } #if (UUE_RINGQUEUE_PROFILE == STD_ON) memset(&pThis->statistic, 0, sizeof(pThis->statistic)); #endif return retVal; } //----------------------------------------------------------------------------- /// \brief insert a queue container to the tail of queue /// /// \descr Synchronous. /// /// \param pThis: pointer to the instance of StaticRingQueue /// /// \return UUE_ErrorType, UUE error type /// //----------------------------------------------------------------------------- UUE_ErrorType Queue_Enqueue(StaticRingQueue_t* pThis, void* payload) { UUE_ErrorType retVal = E_UUE_NO_ERROR; ProtocolBuf_t* srcPdu = (ProtocolBuf_t*)payload; if ((pThis == NULL_PTR) || (payload == NULL_PTR)) return E_UUE_BAD_PARAMETER; if (Queue_IsFull(pThis)) return E_UUE_QUEUE_FULL; Uue_NestingLock(); UUE_ASSERT(pThis->tail < pThis->depth); // make a copy of pdu into entity // NOTENOTE: this is not very good idea for queue is just an container, // it should not provide entity relative operation. // maybe we should provide a copy member function for pdu //pThis->entities[pThis->tail].pdu = (ProtocolBuf_t*)payload; ProtocolBuf_t* desPdu = &pThis->entities[pThis->tail].pdu; memcpy(&desPdu->tcb, &srcPdu->tcb, sizeof(TransactionControl_t)); // copy tcb memcpy(desPdu->reqPduBuffer, srcPdu->reqPduBuffer, srcPdu->reqPduLength); // copy request desPdu->reqPduLength = srcPdu->reqPduLength; desPdu->resPduBuffer = srcPdu->resPduBuffer; // assign response pointer desPdu->resPduLength = srcPdu->resPduLength; desPdu->transactionNotifyCallback = srcPdu->transactionNotifyCallback; pThis->tail = (pThis->tail + 1) % pThis->depth; pThis->level++; #if (UUE_RINGQUEUE_PROFILE == STD_ON) if (pThis->statistic.levelMax < pThis->level) { pThis->statistic.levelMax = pThis->level; UUE_ASSERT(pThis->statistic.levelMax <= pThis->depth); // depth not enough warning } #endif TIMESTAMP_TRANSACTION_ENQUEUE(&desPdu->tcb); UUE_ASSERT(pThis->level <= pThis->depth); Uue_NestingUnlock(); return retVal; } //----------------------------------------------------------------------------- /// \brief recycle a queue container from the head of queue /// /// \descr Synchronous. if queue is empty /// /// \param pThis: pointer to the instance of StaticRingQueue /// /// \return UUE_ErrorType, UUE error type /// //----------------------------------------------------------------------------- UUE_ErrorType Queue_Dequeue(StaticRingQueue_t* pThis) { UUE_ErrorType retVal = E_UUE_NO_ERROR; if (pThis == NULL_PTR) return E_UUE_BAD_PARAMETER; Uue_NestingLock(); if (!Queue_IsEmpty(pThis)) { // reset entity state, see NOTENOTE above //pThis->entities[pThis->head].pdu = (ProtocolBuf_t*)NULL_PTR; ProtocolBuf_t* desPdu = &pThis->entities[pThis->head].pdu; memset(&desPdu->tcb, 0, sizeof(TransactionControl_t)); desPdu->reqPduLength = 0; desPdu->resPduBuffer = 0; desPdu->resPduLength = 0; pThis->head = (pThis->head + 1) % pThis->depth; UUE_ASSERT(pThis->level > 0); pThis->level--; } else { retVal = E_UUE_INVD_OPERATION; } Uue_NestingUnlock(); return retVal; } uint8 Queue_GetDepth(StaticRingQueue_t* pThis) { UUE_ASSERT(pThis != NULL_PTR); return pThis->depth; } uint8 Queue_GetLevel(StaticRingQueue_t* pThis) { UUE_ASSERT(pThis != NULL_PTR); return pThis->level; } //----------------------------------------------------------------------------- /// \brief get a container to be process /// /// \descr Synchronous. get container where head point to. /// /// \param pThis: pointer to the instance of StaticRingQueue /// /// \return UUE_ErrorType, UUE error type /// //----------------------------------------------------------------------------- QueueEntity_t* Queue_GetEntity(StaticRingQueue_t* pThis) { QueueEntity_t* retVal = (QueueEntity_t*)NULL_PTR; if (pThis == NULL_PTR) return retVal; Uue_NestingLock(); retVal = &pThis->entities[pThis->head]; Uue_NestingUnlock(); return retVal; } //----------------------------------------------------------------------------- /// \brief check if queue is empty /// /// \descr synchronous. Queue is empty when head = tail AND head entity is null /// /// \param pThis: pointer to the instance of StaticRingQueue /// /// \return uint8: considering as boolean /// //----------------------------------------------------------------------------- uint8 Queue_IsEmpty(StaticRingQueue_t* pThis) { uint8 retVal = 0; Uue_NestingLock(); if ((pThis->tail == pThis->head) && (pThis->level == 0)) { retVal = 1; } Uue_NestingUnlock(); return retVal; } //----------------------------------------------------------------------------- /// \brief check if queue is full /// /// \descr synchronous. Queue is full when head = tail AND head entity is used /// /// \param pThis: pointer to the instance of StaticRingQueue /// /// \return uint8: considering as boolean /// //----------------------------------------------------------------------------- uint8 Queue_IsFull(StaticRingQueue_t* pThis) { uint8 retVal = 0; Uue_NestingLock(); if ((pThis->tail == pThis->head) && (pThis->level == pThis->depth)) { retVal = 1; } Uue_NestingUnlock(); return retVal; }