QP/C
qa_fifo.c
Go to the documentation of this file.
00001 /*****************************************************************************
00002 * Product: QF/C
00003 * Last Updated for Version: 4.4.00
00004 * Date of the Last Update:  Jan 14, 2012
00005 *
00006 *                    Q u a n t u m     L e a P s
00007 *                    ---------------------------
00008 *                    innovating embedded systems
00009 *
00010 * Copyright (C) 2002-2012 Quantum Leaps, LLC. All rights reserved.
00011 *
00012 * This software may be distributed and modified under the terms of the GNU
00013 * General Public License version 2 (GPL) as published by the Free Software
00014 * Foundation and appearing in the file GPL.TXT included in the packaging of
00015 * this file. Please note that GPL Section 2[b] requires that all works based
00016 * on this software must also be made publicly available under the terms of
00017 * the GPL ("Copyleft").
00018 *
00019 * Alternatively, this software may be distributed and modified under the
00020 * terms of Quantum Leaps commercial licenses, which expressly supersede
00021 * the GPL and are specifically designed for licensees interested in
00022 * retaining the proprietary status of their code.
00023 *
00024 * Contact information:
00025 * Quantum Leaps Web site:  http://www.quantum-leaps.com
00026 * e-mail:                  info@quantum-leaps.com
00027 *****************************************************************************/
00028 #include "qf_pkg.h"
00029 #include "qassert.h"
00030 
00031 Q_DEFINE_THIS_MODULE("qa_fifo")
00032 
00033 
00042 /*..........................................................................*/
00043 #ifndef Q_SPY
00044 void QActive_postFIFO(QActive *me, QEvent const *e) {
00045 #else
00046 void QActive_postFIFO(QActive *me, QEvent const *e, void const *sender) {
00047 #endif
00048 
00049     QF_CRIT_STAT_
00050     QF_CRIT_ENTRY_();
00051 
00052     QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_POST_FIFO, QS_aoObj_, me)
00053         QS_TIME_();                                            /* timestamp */
00054         QS_OBJ_(sender);                               /* the sender object */
00055         QS_SIG_(e->sig);                         /* the signal of the event */
00056         QS_OBJ_(me);                      /* this active object (recipient) */
00057         QS_U8_(QF_EVT_POOL_ID_(e));             /* the pool Id of the event */
00058         QS_U8_(QF_EVT_REF_CTR_(e));           /* the ref count of the event */
00059         QS_EQC_(me->eQueue.nFree);                /* number of free entries */
00060         QS_EQC_(me->eQueue.nMin);             /* min number of free entries */
00061     QS_END_NOCRIT_()
00062 
00063     if (QF_EVT_POOL_ID_(e) != (uint8_t)0) {          /* is it a pool event? */
00064         QF_EVT_REF_CTR_INC_(e);          /* increment the reference counter */
00065     }
00066 
00067     if (me->eQueue.frontEvt == (QEvent *)0) {               /* empty queue? */
00068         me->eQueue.frontEvt = e;                  /* deliver event directly */
00069         QACTIVE_EQUEUE_SIGNAL_(me);               /* signal the event queue */
00070     }
00071     else {         /* queue is not empty, insert event into the ring-buffer */
00072             /* the queue must be able to accept the event (cannot overflow) */
00073         Q_ASSERT(me->eQueue.nFree != (QEQueueCtr)0);
00074                                 /* insert event into the ring buffer (FIFO) */
00075         QF_PTR_AT_(me->eQueue.ring, me->eQueue.head) = e;
00076         if (me->eQueue.head == (QEQueueCtr)0) {   /* need to wrap the head? */
00077             me->eQueue.head = me->eQueue.end;                /* wrap around */
00078         }
00079         --me->eQueue.head;
00080 
00081         --me->eQueue.nFree;                 /* update number of free events */
00082         if (me->eQueue.nMin > me->eQueue.nFree) {
00083             me->eQueue.nMin = me->eQueue.nFree;        /* update min so far */
00084         }
00085     }
00086     QF_CRIT_EXIT_();
00087 }