Linux Face / QPFramework
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers qpset.h Source File

qpset.h

Go to the documentation of this file.
00001 //////////////////////////////////////////////////////////////////////////////
00002 // Product: QF/C++
00003 // Last Updated for Version: 4.1.00
00004 // Date of the Last Update:  Oct 09, 2009
00005 //
00006 //                    Q u a n t u m     L e a P s
00007 //                    ---------------------------
00008 //                    innovating embedded systems
00009 //
00010 // Copyright (C) 2002-2009 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 #ifndef qpset_h
00029 #define qpset_h
00030 
00031 /// \file
00032 /// \ingroup qf qk
00033 /// \brief platform-independent priority sets of 8 or 64 elements.
00034 ///
00035 /// This header file must be included in those QF ports that use the
00036 /// cooperative multitasking QF scheduler or the QK.
00037 
00038                       // external declarations of QF lookup tables used inline
00039 extern uint8_t const Q_ROM Q_ROM_VAR QF_log2Lkup[256];
00040 extern uint8_t const Q_ROM Q_ROM_VAR QF_pwr2Lkup[65];
00041 extern uint8_t const Q_ROM Q_ROM_VAR QF_invPwr2Lkup[65];
00042 extern uint8_t const Q_ROM Q_ROM_VAR QF_div8Lkup[65];
00043 
00044 //////////////////////////////////////////////////////////////////////////////
00045 /// \brief Priority Set of up to 8 elements for building various schedulers,
00046 /// but also useful as a general set of up to 8 elements of any kind.
00047 ///
00048 /// The priority set represents the set of active objects that are ready to
00049 /// run and need to be considered by scheduling processing. The set is capable
00050 /// of storing up to 8 priority levels.
00051 class QPSet8 {
00052 protected:
00053     //////////////////////////////////////////////////////////////////////////
00054     /// \brief bimask representing elements of the set
00055     uint8_t m_bits;
00056 
00057 public:
00058 
00059     /// \brief the function evaluates to TRUE if the priority set is empty,
00060     /// which means that no active objects are ready to run.
00061     uint8_t isEmpty(void) volatile {
00062         return (uint8_t)(m_bits == (uint8_t)0);
00063     }
00064 
00065     /// \brief the function evaluates to TRUE if the priority set has elements,
00066     /// which means that some active objects are ready to run.
00067     uint8_t notEmpty(void) volatile {
00068         return (uint8_t)(m_bits != (uint8_t)0);
00069     }
00070 
00071     /// \brief the function evaluates to TRUE if the priority set has the
00072     /// element \a n.
00073     uint8_t hasElement(uint8_t n) volatile {
00074         return (uint8_t)((m_bits & Q_ROM_BYTE(QF_pwr2Lkup[n])) != 0);
00075     }
00076 
00077     /// \brief insert element \a n into the set, n = 1..8
00078     void insert(uint8_t n) volatile {
00079         m_bits |= Q_ROM_BYTE(QF_pwr2Lkup[n]);
00080     }
00081 
00082     /// \brief remove element \a n from the set, n = 1..8
00083     void remove(uint8_t n) volatile {
00084         m_bits &= Q_ROM_BYTE(QF_invPwr2Lkup[n]);
00085     }
00086 
00087     /// \brief find the maximum element in the set,
00088     /// \note returns zero if the set is empty
00089     uint8_t findMax(void) volatile {
00090         return Q_ROM_BYTE(QF_log2Lkup[m_bits]);
00091     }
00092 
00093     friend class QPSet64;
00094 };
00095 
00096 //////////////////////////////////////////////////////////////////////////////
00097 /// \brief Priority Set of up to 64 elements for building various schedulers,
00098 /// but also useful as a general set of up to 64 elements of any kind.
00099 ///
00100 /// The priority set represents the set of active objects that are ready to
00101 /// run and need to be considered by scheduling processing. The set is capable
00102 /// of storing up to 64 priority levels.
00103 ///
00104 /// The priority set allows to build cooperative multitasking schedulers
00105 /// to manage up to 64 tasks. It is also used in the Quantum Kernel (QK)
00106 /// preemptive scheduler.
00107 ///
00108 /// The inherited 8-bit set is used as the 8-elemtn set of of 8-bit subsets
00109 /// Each bit in the super.bits set represents a subset (8-elements)
00110 /// as follows: \n
00111 /// bit 0 in this->m_bits is 1 when subset[0] is not empty \n
00112 /// bit 1 in this->m_bits is 1 when subset[1] is not empty \n
00113 /// bit 2 in this->m_bits is 1 when subset[2] is not empty \n
00114 /// bit 3 in this->m_bits is 1 when subset[3] is not empty \n
00115 /// bit 4 in this->m_bits is 1 when subset[4] is not empty \n
00116 /// bit 5 in this->m_bits is 1 when subset[5] is not empty \n
00117 /// bit 6 in this->m_bits is 1 when subset[6] is not empty \n
00118 /// bit 7 in this->m_bits is 1 when subset[7] is not empty \n
00119 class QPSet64 : public QPSet8 {
00120 
00121     /// \brief subsets representing elements in the set as follows: \n
00122     /// m_subset[0] represent elements  1..8  \n
00123     /// m_subset[1] represent elements  9..16 \n
00124     /// m_subset[2] represent elements 17..24 \n
00125     /// m_subset[3] represent elements 25..32 \n
00126     /// m_subset[4] represent elements 33..40 \n
00127     /// m_subset[5] represent elements 41..48 \n
00128     /// m_subset[6] represent elements 49..56 \n
00129     /// m_subset[7] represent elements 57..64 \n
00130     QPSet8 m_subset[8];
00131 
00132 public:
00133 
00134     /// \brief the function evaluates to TRUE if the priority set has the
00135     /// element \a n.
00136     uint8_t hasElement(uint8_t n) volatile {
00137          return m_subset[Q_ROM_BYTE(QF_div8Lkup[n])].QPSet8::hasElement(n);
00138     }
00139 
00140     /// \brief insert element \a n into the set, n = 1..64
00141     void insert(uint8_t n) volatile {
00142         QPSet8::insert(Q_ROM_BYTE(QF_div8Lkup[n]) + 1);
00143         m_subset[Q_ROM_BYTE(QF_div8Lkup[n])].QPSet8::insert(n);
00144     }
00145 
00146     /// \brief remove element \a n from the set, n = 1..64
00147     void remove(uint8_t n) volatile {
00148         if ((m_subset[Q_ROM_BYTE(QF_div8Lkup[n])].m_bits
00149                  &= Q_ROM_BYTE(QF_invPwr2Lkup[n])) == (uint8_t)0)
00150         {
00151             QPSet8::remove(Q_ROM_BYTE(QF_div8Lkup[n]) + 1);
00152         }
00153     }
00154 
00155     /// \brief find the maximum element in the set,
00156     /// \note returns zero if the set is empty
00157     uint8_t findMax(void) volatile {
00158         if (m_bits != (uint8_t)0) {
00159             uint8_t n = (uint8_t)(Q_ROM_BYTE(QF_log2Lkup[m_bits]) - 1);
00160             return (uint8_t)(Q_ROM_BYTE(QF_log2Lkup[m_subset[n].m_bits])
00161                              + (n << 3));
00162         }
00163         else {
00164             return (uint8_t)0;
00165         }
00166     }
00167 };
00168 
00169 #endif                                                              // qpset_h
00170