⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 queuetemplate.h

📁 Linux下比较早的基于命令行的DVD播放器
💻 H
字号:
//// Copyright (c) 2003 by Istv醤 V醨adi//// This file is part of dxr3Player, a DVD player written specifically // for the DXR3 (aka Hollywood+) decoder card.// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA#ifndef DXR3PLAYER_SCHED_QUEUETEMPLATE_H#define DXR3PLAYER_SCHED_QUEUETEMPLATE_H//------------------------------------------------------------------------------#include "sched/Scheduler.h"#include "sched/WaitCondition.h"//------------------------------------------------------------------------------namespace sched {//------------------------------------------------------------------------------/** * Template for queues. */template <typename valueT>class QueueTemplate{public:    /**     * The value type.     */    typedef valueT valueType;private:    /**     * The name of the queue.     */    const char* name;    /**     * The capacity of the queue.     */    size_t capacity;    /**     * The invalid value.     */    valueT invalidValue;    /**     * The elements in the queue.     */    valueT* elements;    /**     * The index of the first element inserted.     */    size_t firstIndex;    /**     * The size of the queue.     */    size_t size;    /**     * The condition signalling if one can put a value into the queue.     */    WaitCondition canPut;    /**     * The condition signalling if one can get a value from the queue.     */    WaitCondition canGet;public:    /**     * Construct a queue with the given capacity. It should be     * positive.     */    explicit QueueTemplate(const char* name,                           size_t capacity,                            valueT invalidValue = valueT());    /**     * Destruct the queue.     */    virtual ~QueueTemplate();    /**     * Reset the queue. It removes all entries.     */    virtual void reset();    /**     * Check if the queue is empty or not.     */    bool isEmpty() const;    /**     * Check if the queue is full or not.     */    bool isFull() const;    /**     * Get the size of the queue, i.e. the number of elements in it.     */    size_t getSize() const;    /**     * Put the given value into the queue. If there is space in the     * queue, the value will be put into it and the function returns     * immediately. Otherwise an interruptible wait begins.     *     * @param timeout if given, the waiting will last at most until     * the given time has passed     *     * @return if the value could be put into the queue.     */    bool put(valueT value, millis_t timeout = INVALID_MILLIS);    /**     * Put the given value into the queue. If there is space in the     * queue, it yields the processor, and puts the value into the     * queue, when it gets the control back. Otherwise an     * interruptible wait begins.     *     * @param timeout if given, the waiting will last at most until     * the given time has passed     *     * @return if the value could be put into the queue.     */    bool putYielding(valueT value, millis_t timeout = INVALID_MILLIS);    /**     * Get a value from the queue. If the queue can be consumed, the     * value will be returned immediately. Otherwise an interruptible     * wait begins.     *     * @param timeout if given, the waiting will last at most until     * the given time has passed     *     * @return the value if it could be retrieved or invalidValue if not.     */    valueT get(millis_t timeout = INVALID_MILLIS);    /**     * Get a value from the queue. If the queue can be consumed, it     * will yield the processor and return the value when it gets the     * control back. Otherwise an interruptible wait begins.     *     * @param timeout if given, the waiting will last at most until     * the given time has passed     *     * @return the value if it could be retrieved or invalidValue if not.     */    valueT getYielding(millis_t timeout = INVALID_MILLIS);    /**     * Flush the queue.      *     * This implementation does nothing, but queues requiring a     * minimal fill level before signalling the consumer may want to     * use it to force this signalling, even before the minimal fill level.     */    virtual void flush();    /**     * Print the values.     */    void printValues() const;protected:    /**     * Check if a new entry can be put in the queue. With this      * implementation, it is possible if the queue is not full.     */    virtual bool canProduce();    /**     * Schedule the producer, if possible.     */    void scheduleProducer();    /**     * Check if the queue can be consumed. With this implementation,     * the queue can be consumed if it is not empty. But other     * implementations may have other requirements, such as achieving     * a minimal number of entries.     */    virtual bool canConsume();    /**     * Schedule the consumer, if possible.     */    void scheduleConsumer();private:    /**     * Enlarge the storage.     */    void enlargeElements();    /**     * Put the value into the queue.     */    bool put(valueT value, millis_t timeout, bool yielding);    /**     * Get a value from the queue     */    valueT get(millis_t timeout, bool yielding);};//------------------------------------------------------------------------------// Template definitions//------------------------------------------------------------------------------template <typename valueT>QueueTemplate<valueT>::QueueTemplate(const char* name,                                     size_t capacity,                                      valueT invalidValue) :    name(name),    capacity(capacity),    invalidValue(invalidValue),    elements(new valueT[capacity]),    firstIndex(0),    size(0),    canPut(name, "canPut"),    canGet(name, "canGet"){    assert(capacity>0);}//------------------------------------------------------------------------------template <typename valueT>QueueTemplate<valueT>::~QueueTemplate(){    delete[] elements;}//------------------------------------------------------------------------------template <typename valueT>void QueueTemplate<valueT>::reset(){    while(size>0) {        (elements+firstIndex)->~valueT();        ++firstIndex; firstIndex%=capacity; --size;    }    scheduleProducer();}//------------------------------------------------------------------------------template <typename valueT>inline bool QueueTemplate<valueT>::isEmpty() const{    return size==0;}//------------------------------------------------------------------------------template <typename valueT>inline bool QueueTemplate<valueT>::isFull() const{    return size>=capacity;}//------------------------------------------------------------------------------template <typename valueT>inline size_t QueueTemplate<valueT>::getSize() const{    return size;}//------------------------------------------------------------------------------template <typename valueT>inline bool QueueTemplate<valueT>::put(valueT value, millis_t timeout){    return put(value, timeout, false);}//------------------------------------------------------------------------------template <typename valueT>inline bool QueueTemplate<valueT>::putYielding(valueT value, millis_t timeout){    return put(value, timeout, true);}//------------------------------------------------------------------------------template <typename valueT>inline valueT QueueTemplate<valueT>::get(millis_t timeout){    return get(timeout, false);}//------------------------------------------------------------------------------template <typename valueT>inline valueT QueueTemplate<valueT>::getYielding(millis_t timeout){    return get(timeout, true);}//------------------------------------------------------------------------------template <typename valueT>void QueueTemplate<valueT>::flush(){}//------------------------------------------------------------------------------template <typename valueT>void QueueTemplate<valueT>::printValues() const{    char buffer[256];    for(size_t i = 0; i<size; ++i) {        elements[(i+firstIndex)%capacity]->getDescription(buffer, sizeof(buffer));        Log::debug("    element #%u: %s\n", i, buffer);    }}//------------------------------------------------------------------------------template <typename valueT>bool QueueTemplate<valueT>::canProduce(){    return !isFull();}//------------------------------------------------------------------------------template <typename valueT>void QueueTemplate<valueT>::scheduleProducer(){    if (canProduce()) {        canPut.set();    }}//------------------------------------------------------------------------------template <typename valueT>bool QueueTemplate<valueT>::canConsume(){    return !isEmpty();}//------------------------------------------------------------------------------template <typename valueT>void QueueTemplate<valueT>::scheduleConsumer(){    if (canConsume()) {        canGet.set();    }}//------------------------------------------------------------------------------template <typename valueT>bool QueueTemplate<valueT>::put(valueT value, millis_t timeout, bool yielding){    if (canProduce() && yielding) {        Scheduler::yield(name);    }    if (!canProduce()) {        Scheduler::waitInterruptible(canPut, timeout);    }    if (!canProduce() || Scheduler::isInterrupted()) return false;    size_t nextIndex = (firstIndex + size)%capacity;    new (static_cast<void*>(elements + nextIndex)) valueT(value);    ++size;    scheduleConsumer();    return true;}//------------------------------------------------------------------------------template <typename valueT>valueT QueueTemplate<valueT>::get(millis_t timeout, bool yielding){    if (canConsume() && yielding) {        Scheduler::yield(name);    }    if (!canConsume()) {        Scheduler::waitInterruptible(canGet, timeout);    }    if (!canConsume() || Scheduler::isInterrupted()) return invalidValue;        valueT v(elements[firstIndex]);    (elements+firstIndex)->~valueT();    ++firstIndex; firstIndex%=capacity; --size;    scheduleProducer();    return v;}//------------------------------------------------------------------------------} /* namespace sched *///------------------------------------------------------------------------------#endif // DXR3PLAYER_SCHED_QUEUETEMPLATE_H// Local variables:// mode: c++// End:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -