Linux Face / QPFramework
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers qf_pspub.cpp Source File

qf_pspub.cpp

Go to the documentation of this file.
00001 //////////////////////////////////////////////////////////////////////////////
00002 // Product: QF/C++
00003 // Last Updated for Version: 4.0.00
00004 // Date of the Last Update:  Apr 07, 2008
00005 //
00006 //                    Q u a n t u m     L e a P s
00007 //                    ---------------------------
00008 //                    innovating embedded systems
00009 //
00010 // Copyright (C) 2002-2008 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(qf_pspub)
00032 
00033 /// \file
00034 /// \ingroup qf
00035 /// \brief QF::publish() implementation.
00036 
00037 //............................................................................
00038 void QF::publish(QEvent const *e) {
00039          // make sure that the published signal is within the configured range
00040     Q_REQUIRE(e->sig < QF_maxSignal_);
00041 
00042     QF_INT_LOCK_KEY_
00043     QF_INT_LOCK_();
00044 
00045     QS_BEGIN_NOLOCK_(QS_QF_PUBLISH, (void *)0, (void *)0)
00046         QS_TIME_();                                           // the timestamp
00047         QS_SIG_(e->sig);                            // the signal of the event
00048         QS_U8_(e->dynamic_);            // the dynamic attributes of the event
00049     QS_END_NOLOCK_()
00050 
00051     if (e->dynamic_ != (uint8_t)0) {                 // is it a dynamic event?
00052         //lint -e1773                               Attempt to cast away const
00053         ++((QEvent *)e)->dynamic_;      // increment reference counter, NOTE01
00054                    // NOTE: cast the 'const' away, which is legitimate because
00055                    // it's a dynamic event */
00056     }
00057     QF_INT_UNLOCK_();
00058 
00059 #if (QF_MAX_ACTIVE <= 8)
00060     uint8_t tmp = QF_subscrList_[e->sig].m_bits[0];
00061     while (tmp != (uint8_t)0) {
00062         uint8_t p = Q_ROM_BYTE(QF_log2Lkup[tmp]);
00063         tmp &= Q_ROM_BYTE(QF_invPwr2Lkup[p]);      // clear the subscriber bit
00064         Q_ASSERT(active_[p] != (QActive *)0);            // must be registered
00065 
00066         active_[p]->postFIFO(e);  // internally asserts if the queue overflows
00067     }
00068 #else
00069     uint8_t i = Q_DIM(QF_subscrList_[0].m_bits);// number of bytes in the list
00070     do {                       // go through all bytes in the subsciption list
00071         --i;
00072         uint8_t tmp = QF_subscrList_[e->sig].m_bits[i];
00073         while (tmp != (uint8_t)0) {
00074             uint8_t p = Q_ROM_BYTE(QF_log2Lkup[tmp]);
00075             tmp &= Q_ROM_BYTE(QF_invPwr2Lkup[p]);  // clear the subscriber bit
00076             p = (uint8_t)(p + (i << 3));                // adjust the priority
00077             Q_ASSERT(active_[p] != (QActive *)0);        // must be registered
00078 
00079                        // postFIFO() internally asserts if the queue overflows
00080             active_[p]->postFIFO(e);
00081         }
00082     } while (i != (uint8_t)0);
00083 #endif
00084 
00085     gc(e);                            // run the garbage collector, see NOTE01
00086 }
00087 
00088 //////////////////////////////////////////////////////////////////////////////
00089 // NOTE01:
00090 // QF::publish() increments the reference counter to prevent premature
00091 // recycling of the event while the multicasting is still in progress.
00092 // At the end of the function, the garbage collector step decrements the
00093 // reference counter and recycles the event if the counter drops to zero.
00094 // This covers the case when the event was published without any subscribers.
00095 //