res_list.hh

来自「M5,一个功能强大的多处理器系统模拟器.很多针对处理器架构,性能的研究都使用它作」· HH 代码 · 共 759 行 · 第 1/2 页

HH
759
字号
/* * Copyright (c) 2001, 2002, 2003, 2004, 2005 * The Regents of The University of Michigan * All Rights Reserved * * This code is part of the M5 simulator. * * Permission is granted to use, copy, create derivative works and * redistribute this software and such derivative works for any * purpose, so long as the copyright notice above, this grant of * permission, and the disclaimer below appear in all copies made; and * so long as the name of The University of Michigan is not used in * any advertising or publicity pertaining to the use or distribution * of this software without specific, written prior authorization. * * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE * UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND * WITHOUT WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER * EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE * LIABLE FOR ANY DAMAGES, INCLUDING DIRECT, SPECIAL, INDIRECT, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM * ARISING OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF SUCH * DAMAGES. * * Authors: Steven E. Raasch *          Nathan L. Binkert */#ifndef __RES_LIST_HH__#define __RES_LIST_HH__#include "base/cprintf.hh"#include <assert.h>#define DEBUG_REMOVE 0#define DEBUG_MEMORY 0//#define DEBUG_MEMORY DEBUGclass res_list_base{#if DEBUG_MEMORY  protected:    static long long allocated_elements;    static long long allocated_lists;  public:    long long get_elements(void) {        return allocated_elements;    }    long long get_lists(void) {        return allocated_lists;    }#endif};#if DEBUG_MEMORYextern void what_the(void);#endiftemplate<class T>class res_list : public res_list_base{  public:    class iterator;    class res_element    {        res_element *next;        res_element *prev;        T *data;        bool allocate_data;      public:        //  always adds to the END of the list        res_element(res_element *_prev, bool allocate);        ~res_element();        void dump(void);        friend class res_list<T>;        friend class res_list<T>::iterator;    };    class iterator    {      private:        res_element *p;        friend class res_list<T>;      public:        // Constructors        iterator(res_element *q) : p(q) {}        iterator(void) { p=0; };        void dump(void);        T* data_ptr(void);        res_element *res_el_ptr(void) { return p;}        void point_to(T &d) { p->data = &d; }        iterator next(void) { return iterator(p->next); }        iterator prev(void) { return iterator(p->prev); }        bool operator== (iterator x) { return (x.p == this->p); }        bool operator != (iterator x) { return (x.p != this->p); }        T &operator * (void) { return *(p->data); }        T* operator -> (void) { return p->data; }        bool isnull(void) { return (p==0); }        bool notnull(void) { return (p!=0); }    };  private:    iterator unused_elements;    iterator head_ptr;    iterator tail_ptr;    unsigned base_elements;    unsigned extra_elements;    unsigned active_elements;    bool     allocate_storage;    unsigned build_size;    int remove_count;    //    //  Allocate new elements, and assign them to the unused_elements    //  list.    //    unsigned allocate_elements(unsigned num, bool allocate_storage);  public:    //    //  List Constructor    //    res_list(unsigned size, bool alloc_storage = false,             unsigned build_sz = 5);    //    //  List Destructor    //    ~res_list();    iterator head(void) {return head_ptr;};    iterator tail(void) {return tail_ptr;};    unsigned num_free(void) { return size() - count(); }    unsigned size(void) { return base_elements + extra_elements; }    unsigned count(void) { return active_elements; }    bool empty(void) { return count() == 0; }    bool full(void);    //    //  Insert with data copy    //    iterator insert_after(iterator prev, T *d);    iterator insert_after(iterator prev, T &d);    iterator insert_before(iterator prev, T *d);    iterator insert_before(iterator prev, T &d);    //    //  Insert new list element (no data copy)    //    iterator insert_after(iterator prev);    iterator insert_before(iterator prev);    iterator add_tail(T *d) { return insert_after(tail_ptr, d); }    iterator add_tail(T &d) { return insert_after(tail_ptr, d); }    iterator add_tail(void) { return insert_after(tail_ptr); }    iterator add_head(T *d) { return insert_before(head_ptr, d); }    iterator add_head(T &d) { return insert_before(head_ptr, d); }    iterator add_head(void) { return insert_before(head_ptr); }    iterator remove(iterator q);    iterator remove_head(void) {return remove(head_ptr);}    iterator remove_tail(void) {return remove(tail_ptr);}    bool in_list(iterator j);    void free_extras(void);    void clear(void);    void dump(void);    void raw_dump(void);};template <class T>inlineres_list<T>::res_element::res_element(res_element *_prev, bool allocate){    allocate_data = allocate;    prev = _prev;    next = 0;    if (prev)        prev->next = this;    if (allocate)        data = new T;    else        data = 0;#if DEBUG_MEMORY    ++allocated_elements;#endif}template <class T>inlineres_list<T>::res_element::~res_element(void){    if (prev)        prev->next = next;    if (next)        next->prev = prev;    if (allocate_data)        delete data;#if DEBUG_MEMORY    --allocated_elements;#endif}template <class T>inline voidres_list<T>::res_element::dump(void){    cprintf("  prev = %#x\n", prev);    cprintf("  next = %#x\n", next);    cprintf("  data = %#x\n", data);}template <class T>inline voidres_list<T>::iterator::dump(void){    if (p && p->data)        p->data->dump();    else {        if (!p)            cprintf("  Null Pointer\n");        else            cprintf("  Null 'data' Pointer\n");    }}template <class T>inline T *res_list<T>::iterator::data_ptr(void){    if (p)        return p->data;    else        return 0;}////  Allocate new elements, and assign them to the unused_elements//  list.//template <class T>inline unsignedres_list<T>::allocate_elements(unsigned num, bool allocate_storage){    res_element *pnew, *plast = 0, *pfirst=0;    for (int i=0; i<num; ++i) {        pnew = new res_element(plast, allocate_storage);        if (i==0)            pfirst = pnew;        plast = pnew;    }    if (unused_elements.notnull()) {        //  Add these new elements to the front of the list        plast->next = unused_elements.res_el_ptr();        unused_elements.res_el_ptr()->prev = plast;    }    unused_elements = iterator(pfirst);    return num;}template <class T>inlineres_list<T>::res_list(unsigned size, bool alloc_storage, unsigned build_sz){#if DEBUG_MEMORY    ++allocated_lists;#endif    extra_elements = 0;    active_elements = 0;    build_size = build_sz;    allocate_storage = alloc_storage;    remove_count = 0;    //  Create the new elements    base_elements = allocate_elements(size, alloc_storage);    //  The list of active elements    head_ptr = iterator(0);    tail_ptr = iterator(0);}////  List Destructor//template <class T>inlineres_list<T>::~res_list(void){    iterator n;#if DEBUG_MEMORY    --allocated_lists;#endif    //  put everything into the unused list    clear();    //  rudely delete all the res_elements    for (iterator p = unused_elements;         p.notnull();         p = n) {        n = p.next();        //  delete the res_element        //  (it will take care of deleting the data)        delete p.res_el_ptr();    }}template <class T>inline boolres_list<T>::full(void){    if (build_size)        return false;    else        return unused_elements.isnull();}////  Insert with data copy//template <class T>inline typename res_list<T>::iteratorres_list<T>::insert_after(iterator prev, T *d){    iterator p;    if (!allocate_storage)        this->panic("Can't copy data... not allocating storage");    p = insert_after(prev);    if (p.notnull())        *p = *d;    return p;}template <class T>inline typename res_list<T>::iteratorres_list<T>::insert_after(iterator prev, T &d){    iterator p;    p = insert_after(prev);    if (p.notnull()) {        if (allocate_storage) {            //  if we allocate storage, then copy the contents of the            //  specified object to our object            *p = d;

⌨️ 快捷键说明

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