Ejemplo n.º 1
0
//............................................................................
QEvent *QF::new_(uint16_t evtSize, QSignal sig) {
                    // find the pool id that fits the requested event size ...
    uint8_t id = (uint8_t)0;
    while (evtSize > QF_EPOOL_EVENT_SIZE_(QF_pool_[id])) {
        ++id;
        Q_ASSERT(id < QF_maxPool_);      // cannot run out of registered pools
    }

    QS_INT_LOCK_KEY_
    QS_BEGIN_(QS_QF_NEW, (void *)0, (void *)0)
        QS_TIME_();                                               // timestamp
        QS_EVS_(evtSize);                             // the size of the event
        QS_SIG_(sig);                               // the signal of the event
    QS_END_()

    QEvent *e;
    QF_EPOOL_GET_(QF_pool_[id], e);
    Q_ASSERT(e != (QEvent *)0);             // pool must not run out of events

    e->sig = sig;                                 // set signal for this event

                                 // store the dynamic attributes of the event:
                                 // the pool ID and the reference counter == 0
    e->dynamic_ = (uint8_t)((id + 1) << 6);
    return e;
}
Ejemplo n.º 2
0
/*..........................................................................*/
QEvt *QF_newX_(uint_t const evtSize,
               uint_t const margin, enum_t const sig)
{
    QEvt *e;
    uint_t idx;
    QS_CRIT_STAT_

              /* find the pool index that fits the requested event size ... */
    for (idx = (uint_t)0; idx < QF_maxPool_; ++idx) {
        if (evtSize <= QF_EPOOL_EVENT_SIZE_(QF_pool_[idx])) {
            break;
        }
    }
    Q_ASSERT(idx < QF_maxPool_);      /* cannot run out of registered pools */

    QS_BEGIN_(QS_QF_NEW, (void *)0, (void *)0)
        QS_TIME_();                                            /* timestamp */
        QS_EVS_((QEvtSize)evtSize);                /* the size of the event */
        QS_SIG_((QSignal)sig);                   /* the signal of the event */
    QS_END_()

    QF_EPOOL_GET_(QF_pool_[idx], e, margin); /* get e -- platform-dependent */

    if (e != (QEvt *)0) {                     /* was e allocated correctly? */
        e->sig = (QSignal)sig;                 /* set signal for this event */
        e->poolId_ = (uint8_t)(idx + (uint_t)1);       /* store the pool ID */
        e->refCtr_ = (uint8_t)0;          /* set the reference counter to 0 */
    }
    else {                                     /* event cannot be allocated */
        Q_ASSERT(margin != (uint_t)0);     /* must tollerate bad allocation */
    }
    return e;         /* can't be NULL if we can't tollerate bad allocation */
}
Ejemplo n.º 3
0
/*..........................................................................*/
void QF_poolInit(void *poolSto, uint32_t poolSize, QEventSize evtSize) {


                      /* cannot exceed the number of available memory pools */
/* -------------------------------------------------------------------------
   This precondition (see Chapter 6, “Customized Assertions in C/C++”) 
   asserts that the application does not attempt to initialize more than the 
   supported number of event pools (currently three).
   -------------------------------------------------------------------------*/
    Q_REQUIRE(QF_maxPool_ < (uint8_t)Q_DIM(QF_pool_));
    

	        /* please initialize event pools in ascending order of evtSize: */
/* -------------------------------------------------------------------------
	For possibly quick event allocation, the event pool array QF_pool_[]
	must be sorted in ascending order of block sizes. This precondition asserts
	that the application initializes event pools in the increasing order of the
	event sizes. This assertion significantly simplifies the QF_poolInit()
	function without causing any true inconvenience for the application
	implementer.
   -------------------------------------------------------------------------*/    
    Q_REQUIRE((QF_maxPool_ == (uint8_t)0)
              || (QF_EPOOL_EVENT_SIZE_(QF_pool_[QF_maxPool_ - 1]) < evtSize));
                /* perfom the platform-dependent initialization of the pool */
    QF_EPOOL_INIT_(QF_pool_[QF_maxPool_], poolSto, poolSize, evtSize);
    ++QF_maxPool_;                                         /* one more pool */
}
Ejemplo n.º 4
0
/*..........................................................................*/
void QF_poolInit(void *poolSto, uint32_t poolSize, QEventSize evtSize) {
                      /* cannot exceed the number of available memory pools */
    Q_REQUIRE(QF_maxPool_ < (uint8_t)Q_DIM(QF_pool_));
            /* please initialize event pools in ascending order of evtSize: */
    Q_REQUIRE((QF_maxPool_ == (uint8_t)0)
             || (QF_EPOOL_EVENT_SIZE_(QF_pool_[QF_maxPool_ - (uint8_t)1])
                 < evtSize));
                /* perfom the platform-dependent initialization of the pool */
    QF_EPOOL_INIT_(QF_pool_[QF_maxPool_], poolSto, poolSize, evtSize);
    ++QF_maxPool_;                                         /* one more pool */
}
Ejemplo n.º 5
0
/**
* \description
* This function initializes one event pool at a time and must be called
* exactly once for each event pool before the pool can be used.
*
* \arguments
* \arg[in] \c poolSto  pointer to the storage for the event pool
* \arg[in] \c poolSize size of the storage for the pool in bytes
* \arg[in] \c evtSize  the block-size of the pool in bytes, which determines
*             the maximum size of events that can be allocated from the pool.
*
* \note
* You might initialize many event pools by making many consecutive calls
* to the QF_poolInit() function. However, for the simplicity of the internal
* implementation, you must initialize event pools in the ascending order of
* the event size.
*
* Many RTOSes provide fixed block-size heaps, a.k.a. memory pools that can
* be adapted for QF event pools. In case such support is missing, QF provides
* a native QF event pool implementation. The macro #QF_EPOOL_TYPE_ determines
* the type of event pool used by a particular QF port. See structure ::QMPool
* for more information.
*
* \note The actual number of events available in the pool might be actually
* less than (\a poolSize / \a evtSize) due to the internal alignment
* of the blocks that the pool might perform. You can always check the
* capacity of the pool by calling QF_getPoolMin().
*
* \note The dynamic allocation of events is optional, meaning that you
* might choose not to use dynamic events. In that case calling QF_poolInit()
* and using up memory for the memory blocks is unnecessary.
*
* \sa QF initialization example for QF_init()
*/
void QF_poolInit(void * const poolSto, uint_fast16_t const poolSize,
                 uint_fast16_t const evtSize)
{
    /** \pre cannot exceed the number of available memory pools */
    Q_REQUIRE_ID(100, QF_maxPool_ < (uint_fast8_t)Q_DIM(QF_pool_));
    /** \pre please initialize event pools in ascending order of evtSize: */
    Q_REQUIRE_ID(101, (QF_maxPool_ == (uint_fast8_t)0)
        || (QF_EPOOL_EVENT_SIZE_(QF_pool_[QF_maxPool_ - (uint_fast8_t)1])
            < evtSize));

    /* perform the platform-dependent initialization of the pool */
    QF_EPOOL_INIT_(QF_pool_[QF_maxPool_],
                   poolSto, poolSize, evtSize);
    ++QF_maxPool_; /* one more pool */
}
Ejemplo n.º 6
0
//****************************************************************************
/// @description
/// Allocates an event dynamically from one of the QF event pools.
///
/// @param[in] evtSize the size (in bytes) of the event to allocate
/// @param[in] margin  the number of un-allocated events still available
///                    in a given event pool after the allocation completes
/// @param[in] sig     the signal to be assigned to the allocated event
///
/// @returns pointer to the newly allocated event. This pointer can be NULL
/// only if margin!=0 and the event cannot be allocated with the specified
/// margin still available in the given pool.
///
/// @note The internal QF function QP::QF::newX_() raises an assertion when
/// the margin argument is 0 and allocation of the event turns out to be
/// impossible due to event pool depletion, or incorrect (too big) size
/// of the requested event.
///
/// @note The application code should not call this function directly.
/// The only allowed use is thorough the macros Q_NEW() or Q_NEW_X().
///
QEvt *QF::newX_(uint_fast16_t const evtSize,
                uint_fast16_t const margin, enum_t const sig)
{
    uint_fast8_t idx;

    // find the pool id that fits the requested event size ...
    for (idx = static_cast<uint_fast8_t>(0); idx < QF_maxPool_; ++idx) {
        if (evtSize <= QF_EPOOL_EVENT_SIZE_(QF_pool_[idx])) {
            break;
        }
    }
    // cannot run out of registered pools
    Q_ASSERT_ID(310, idx < QF_maxPool_);

    QS_CRIT_STAT_
    QS_BEGIN_(QS_QF_NEW, static_cast<void *>(0), static_cast<void *>(0))
        QS_TIME_();                              // timestamp
        QS_EVS_(static_cast<QEvtSize>(evtSize)); // the size of the event
        QS_SIG_(static_cast<QSignal>(sig));      // the signal of the event
    QS_END_()

    QEvt *e;
    QF_EPOOL_GET_(QF_pool_[idx], e, margin); // get e -- platform-dependent

    // was e allocated correctly?
    if (e != static_cast<QEvt const *>(0)) {
        e->sig     = static_cast<QSignal>(sig); // set the signal
        // store pool ID
        e->poolId_ = static_cast<uint8_t>(
                       idx + static_cast<uint_fast8_t>(1));
        // initialize the reference counter to 0
        e->refCtr_ = static_cast<uint8_t>(0);
    }
    else {
        // event was not allocated, assert that the caller provided non-zero
        // margin, which means that they can tollerate bad allocation
        Q_ASSERT_ID(320, margin != static_cast<uint_fast16_t>(0));
    }
    return e;
}