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 + -
显示快捷键?