Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | /* |
2 | * ========== Copyright Header Begin ========================================== | |
3 | * | |
4 | * OpenSPARC T2 Processor File: Object.h | |
5 | * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. | |
6 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES. | |
7 | * | |
8 | * The above named program is free software; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU General Public | |
10 | * License version 2 as published by the Free Software Foundation. | |
11 | * | |
12 | * The above named program is distributed in the hope that it will be | |
13 | * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 | * General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public | |
18 | * License along with this work; if not, write to the Free Software | |
19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. | |
20 | * | |
21 | * ========== Copyright Header End ============================================ | |
22 | */ | |
23 | #ifndef __Object_h | |
24 | #define __Object_h | |
25 | ||
26 | #include <stdlib.h> | |
27 | #include <string> | |
28 | #include <sstream> | |
29 | #include <fstream> | |
30 | #include <assert.h> | |
31 | #include "List.h" | |
32 | #include "Trace.h" | |
33 | //using namespace std; | |
34 | ||
35 | /** @file Object.h | |
36 | * The Object class is used to represent and organize simulation objects. | |
37 | * | |
38 | * @sa Object_Module | |
39 | */ | |
40 | ||
41 | /** @defgroup Object_Module The Object Module | |
42 | * | |
43 | * All objects are held in the Object tree. This is rooted at a special | |
44 | * pre-defined Object, the rootObject. The rootObject is called "ROOT", | |
45 | * which is both the basename and the fullname of that Object. When | |
46 | * a new Object is constructed it is given a basename, and is associated | |
47 | * with a parent Object (which must already exist). The fullname of an | |
48 | * Object is formed by walking the tree from the rootObject down to that | |
49 | * Object and concatenating the basename of each node in the tree | |
50 | * (including "ROOT" and the basename of that Object) separated by a period. | |
51 | * | |
52 | * The Object class provides basic simulation infrastructure to | |
53 | * objects such as: | |
54 | * - naming and hierarchy (as described above) | |
55 | * - printing: dumping of Object internal state for debug purposes. | |
56 | * - reset: the "resetThis" method of an Object is called to reset the | |
57 | * state of that Object. | |
58 | * - signing: the "signThis" method of an Object is called to create | |
59 | * a Signature for each item that can in a trace. | |
60 | * - tracing: the output of trace data for analysis purposes. | |
61 | * - parameterization: parameters are associated with objects in the Object | |
62 | * tree. Mechanisms are provided to get, set, save and load parameters | |
63 | * using the Param class. | |
64 | * | |
65 | * Simulation objects derive from the Object class and over-ride its | |
66 | * virtual methods (printThis, resetThis, signThis, traceThis, | |
67 | * paramThis) as required. In fact, the Block class derives from Object, | |
68 | * and provides additional mechanism and infrastructure that is appropriate | |
69 | * for system-level performance modelling. Most blocks that model system | |
70 | * hardware will derive from Block instead of from Object. However, if a | |
71 | * a new class of simulation objects is required that does not benefit | |
72 | * from Block, then this can derive directly from Object. | |
73 | * | |
74 | * @{ | |
75 | */ | |
76 | ||
77 | class Parameter; // cross-reference to Parameter from Param.h | |
78 | ||
79 | /** The Object class provides infrastructure and mechanism for the | |
80 | * modelling of simulation objects. | |
81 | */ | |
82 | ||
83 | class Object | |
84 | { | |
85 | friend class ObjectIterator; | |
86 | friend class ObjectArray; | |
87 | ||
88 | public: | |
89 | /** Constructor for Object. | |
90 | * @param s - the basename of the Object. | |
91 | * @param p - the parent of the Object. If this is omitted or if it is | |
92 | * specified as NULL, then the parent will be the rootObject. | |
93 | * | |
94 | * Initially, the Object will have no children and be associated with no | |
95 | * parameters. Child objects and parameters are automatically added to their | |
96 | * parent Object when they are created. | |
97 | */ | |
98 | Object(string s, Object *p=NULL); | |
99 | ||
100 | /** Destructor for Object. This is virtual so that the appropriate | |
101 | * destructor for any derived class is used. */ | |
102 | virtual ~Object(); | |
103 | ||
104 | /** Get the basename of this Object. */ | |
105 | string getBaseName() { return baseName; } | |
106 | ||
107 | /** Get the fullname of this Object. */ | |
108 | string getFullName() { return fullName; } | |
109 | ||
110 | /** Print information about the Object tree rooted at this Object. */ | |
111 | void printTree(ostream &os); | |
112 | ||
113 | /** Print information about this Object to the specified output stream. | |
114 | * The implementation of Object::printThis simply prints the fullname | |
115 | * of this Object. It is a virtual method so that additional functionality | |
116 | * can be provided by a sub-class of Object. */ | |
117 | virtual void printThis(ostream &os); | |
118 | ||
119 | /** Reset the Object tree rooted at this Object. */ | |
120 | void resetTree(); | |
121 | ||
122 | /** The resetThis method is called to place this Object into its | |
123 | * reset state. The implementation of Object::resetThis is empty, | |
124 | * but is a virtual method so that this functionality can be | |
125 | * provided by a sub-class of Object. */ | |
126 | virtual void resetThis() {} | |
127 | ||
128 | /** Produce signature information about the Object tree rooted | |
129 | * at this Object to the specified output file stream. This mechanism | |
130 | * is used to produce the header information for a trace file. */ | |
131 | void signTree(ofstream &ofs); | |
132 | ||
133 | /** The signThis method is called to produce signature information | |
134 | * for this Object to the specified output file stream. The | |
135 | * implementation of Object::signThis is empty, but is a virtual | |
136 | * method so that this functionality can be provided by a | |
137 | * sub-class of Object. */ | |
138 | virtual void signThis(ofstream &ofs) {} | |
139 | ||
140 | /** Produce trace data for the Object tree rooted at this Object. */ | |
141 | void traceTree(); | |
142 | ||
143 | /** Produce trace data for this Object. The implementation of | |
144 | * Object::traceThis is empty, but is a virtual method so that | |
145 | * this functionality can be provided by a sub-class of Object. */ | |
146 | virtual void traceThis() {} | |
147 | ||
148 | /** This static method opens a trace file. | |
149 | * @param filename the name of the trace file to be opened. If not | |
150 | * specified, the default filename is "default.trc". | |
151 | * | |
152 | * Note that only one trace file can be open at a time. If a trace | |
153 | * file is open when traceOpen is called, the old one will be | |
154 | * automatically closed. | |
155 | */ | |
156 | static void traceOpen(const char *filename = "default.trc"); | |
157 | ||
158 | /** This static method closes the currently open trace file. */ | |
159 | static void traceClose(); | |
160 | ||
161 | /** This static method enters a time-stamp record into the trace file. | |
162 | * Usually there is no need to enter explicit time-stamps because | |
163 | * trace file entries will themselves indicate the current time. | |
164 | * However, if there is no trace file activity for extended periods | |
165 | * (e.g. because no values are changing) it can be useful to insert | |
166 | * an explicit time-stamp. A specific example is when a trace file | |
167 | * is closed - in this case, an automatic time-stamp is produced | |
168 | * to ensure that the final time-stamp is captured. */ | |
169 | static void traceStamp(); | |
170 | ||
171 | /** This status method returns the output file stream by reference. */ | |
172 | static ofstream &getTraceFile() { return traceFile; } | |
173 | ||
174 | /** This static method returns a boolean indicating whether a trace | |
175 | * file is open. | |
176 | * @return True if a trace file is open, otherwise false. | |
177 | */ | |
178 | static bool getTracing() { return tracing; } | |
179 | ||
180 | /** The traceMode method is used to set or clear the trace mode for | |
181 | * objects using the Object tree. There is a trace mode variable | |
182 | * maintained for each Object, and this is a bitwise OR of values | |
183 | * from the Trace enumeration. Trace of a particular kind is enabled | |
184 | * for an Object if the trace mode for that kind is set for that Object, | |
185 | * otherwise it is disabled. This method sets or clears bits in the | |
186 | * trace mode, and the change is applied to this Object and to all | |
187 | * objects in the tree rooted at this Object. This provides a powerful | |
188 | * mechanism to set up trace filters. | |
189 | * @param b If true the parameter "t" specifies the kinds of trace | |
190 | * which are to be enabled, otherwise the kinds of trace that | |
191 | * are to be disabled. | |
192 | * @param t Indicates the kinds of trace for which the trace mode | |
193 | * is to be changed. This defaults to all known kinds of Trace. | |
194 | */ | |
195 | void traceMode(bool b, unsigned t=Trace::DEFAULT); | |
196 | ||
197 | /** Returns a boolean indicating whether tracing is enabled for this Object. | |
198 | * @return True if a trace file is open and any kind of trace is enabled | |
199 | * for this Object, otherwise false. | |
200 | */ | |
201 | bool isTracing() { return tracing && (traceType != 0); } | |
202 | ||
203 | /** Returns a boolean indicating whether the specified kind of tracing is | |
204 | * enabled for this Object. | |
205 | * @param t the kind of trace to test for. This parameter is a bitwise | |
206 | * OR of values from the Trace enumeration. | |
207 | * @return True if a trace file is open and any kind of the specified | |
208 | * kinds of trace are enabled for this Object, otherwise false. | |
209 | */ | |
210 | bool isTracing(unsigned t) { return tracing && ((traceType & t) != 0); } | |
211 | ||
212 | /** Propagate the value of all parameters associated with objects in the | |
213 | * Object tree rooted at this Object. This mechanism is invoked when | |
214 | * a parameter file is loaded so that anything dependent on or derived | |
215 | * from a parameter value can be re-evaluated. */ | |
216 | void paramTree(); | |
217 | ||
218 | /** Evaluate the value of all parameters associated with this Object. | |
219 | * The implementation of Object::signThis is empty, but is a virtual | |
220 | * method so that this functionality can be provided by a sub-class | |
221 | * of Object. This mechanism is invoked when a parameter file is | |
222 | * loaded so that anything dependent on or derived from a parameter | |
223 | * value can be re-evaluated. */ | |
224 | virtual void paramThis() {} | |
225 | ||
226 | /** Add the specified parameter to the list of parameters associated with | |
227 | * this Block. */ | |
228 | void addParameter (Parameter *param); | |
229 | ||
230 | /** Print the parameters associated with this Object and with each Object | |
231 | * in the Object tree rooted at this Object to the specified output stream. | |
232 | */ | |
233 | void paramPrint (ostream &os); | |
234 | ||
235 | /** This static method saves all parameters to a parameter file. | |
236 | * @param filename the name of the parameter file to save to. If not | |
237 | * specified, the default filename is "default.prm". | |
238 | */ | |
239 | static void paramSave (const char *filename = "default.prm"); | |
240 | ||
241 | /** Save the parameters associated with this Object and with each Object | |
242 | * in the Object tree rooted at this Object to the specified output file | |
243 | * stream. */ | |
244 | void paramSave (ofstream &ofs); | |
245 | ||
246 | /** This static method loads parameters from a parameter file. | |
247 | * @param filename the name of the parameter file to load from. If not | |
248 | * specified, the default filename is "default.prm". | |
249 | * | |
250 | * Each parameter that appears in the parameter file will be set to | |
251 | * the specified value. Other parameters will be unchanged. | |
252 | */ | |
253 | static void paramLoad (const char *filename = "default.prm"); | |
254 | ||
255 | /** Load the parameters associated with this Object and with each Object | |
256 | * in the Object tree rooted at this Object from the specified string | |
257 | * buffer. */ | |
258 | bool paramLoad (stringbuf &sb); | |
259 | ||
260 | /** Get a pointer to the rootObject. */ | |
261 | static Object *getRoot() { | |
262 | #if 0 | |
263 | // printf("+getRoot\n"); | |
264 | rootObject.parent = NULL; | |
265 | rootObject.baseName = "ROOT"; | |
266 | rootObject.fullName = "ROOT"; | |
267 | rootObject.traceType = 0; | |
268 | rootObject.tracing = false; | |
269 | // printf("-getRoot\n"); | |
270 | #else | |
271 | // printf("+getRoot\n"); | |
272 | rootObject = new Object("ROOT"); | |
273 | // printf("-getRoot\n"); | |
274 | #endif | |
275 | return rootObject; | |
276 | } | |
277 | ||
278 | /** Get a pointer to the nullObject. This is a useful place to hang objects | |
279 | * outside of the root tree. Such objects will not be visited in walks | |
280 | * over the Object tree, and are therefore hidden from the Object tree | |
281 | * print, reset, sign and trace mechanisms. */ | |
282 | static Object *getNull() { | |
283 | #if 0 | |
284 | nullObject.parent = NULL; | |
285 | nullObject.baseName = "NULL"; | |
286 | nullObject.fullName = "NULL"; | |
287 | nullObject.traceType = 0; | |
288 | nullObject.tracing = false; | |
289 | #else | |
290 | nullObject = new Object("NULL"); | |
291 | #endif | |
292 | return nullObject; | |
293 | } | |
294 | ||
295 | protected: | |
296 | Object() {} | |
297 | ||
298 | private: | |
299 | static Object *rootObject; | |
300 | static Object *nullObject; | |
301 | int initialized; | |
302 | static bool tracing; | |
303 | static ofstream traceFile; | |
304 | ||
305 | Object *parent; | |
306 | List<Object> children; | |
307 | List<Parameter> param; | |
308 | string baseName; | |
309 | string fullName; | |
310 | unsigned traceType; | |
311 | }; | |
312 | ||
313 | /** ObjectIterator is used to iterate through the children of an Object. */ | |
314 | ||
315 | class ObjectIterator : public ListIterator<Object> | |
316 | { | |
317 | public: | |
318 | /** Constructor for ObjectIterator. | |
319 | * @param o a pointer to the Object to be iterated over. | |
320 | * | |
321 | * All other methods are inherited, see ListIterator for details. | |
322 | */ | |
323 | ObjectIterator(Object *o) : ListIterator<Object>(&o->children) {} | |
324 | }; | |
325 | ||
326 | /** ObjectArray is used to constructs arrays of Objects, and index into | |
327 | * the array to a Object element. | |
328 | */ | |
329 | ||
330 | class ObjectArray | |
331 | { | |
332 | public: | |
333 | /** Constructor for ObjectArray. | |
334 | * @param n the number of Objects in the array. | |
335 | * @param s the basename for this ObjectArray. The basename of an Object | |
336 | * in the array will be this basename appended by "[i]" where | |
337 | * i is the index of that Object in the array. | |
338 | * @param p the parent Object of this ObjectArray. | |
339 | */ | |
340 | ObjectArray(uint n, string s, Object *p=NULL) | |
341 | { | |
342 | size = n; | |
343 | array = new Object*[size]; | |
344 | for (uint i=0; i<size; i++) { | |
345 | ostringstream o; | |
346 | o << i; | |
347 | array[i] = new Object(s + "[" + o.str() + "]", p); | |
348 | } | |
349 | } | |
350 | ||
351 | /** Destructor for ObjectArray. */ | |
352 | ~ObjectArray() | |
353 | { | |
354 | for (uint i=0; i<size; i++) | |
355 | delete array[i]; | |
356 | delete[] array; | |
357 | } | |
358 | ||
359 | /** Index operator for ObjectArray. This indexes into the ObjectArray | |
360 | * and returns the Object instance at the specified index. */ | |
361 | Object &operator[](uint i) { assert(i < size); return *array[i]; } | |
362 | ||
363 | private: | |
364 | Object **array; | |
365 | uint size; | |
366 | }; | |
367 | ||
368 | /** ObjectArrayOf<T,P> is used to constructs arrays of some type T which is | |
369 | * presumed to be a subclass of Object, where each element in the array | |
370 | * has a parent of type P. The only actual requirement on T | |
371 | * is that it provides a constructor compatible with the Object constructor. | |
372 | * This is useful for creating arrays of some subclass of Object without | |
373 | * having to redeclare an appropriate array class. In practice, this class | |
374 | * is more useful than ObjectArray since interesting Objects must extend | |
375 | * Object. The problem with ObjectArray is that it is statically associated | |
376 | * with the constructor for Object. The use of templates for ObjectArrayOf | |
377 | * ensures that the appropriate constructor for type T is used, and that | |
378 | * the type of the parent P can be passed through with a type cast. | |
379 | */ | |
380 | ||
381 | template<class T, class P> class ObjectArrayOf | |
382 | { | |
383 | public: | |
384 | /** Constructor for ObjectArrayOf. | |
385 | * @param n the number of Objects in the array. | |
386 | * @param s the basename for this ObjectArrayOf. The basename of an Object | |
387 | * in the array will be this basename appended by "[i]" where | |
388 | * i is the index of that Object in the array. | |
389 | * @param p the parent Object of this ObjectArrayOf. | |
390 | */ | |
391 | ObjectArrayOf(uint n, string s, P *p=NULL) | |
392 | { | |
393 | size = n; | |
394 | array = new T*[size]; | |
395 | for (uint i=0; i<size; i++) { | |
396 | ostringstream o; | |
397 | o << i; | |
398 | array[i] = new T(s + "[" + o.str() + "]", p); | |
399 | } | |
400 | } | |
401 | ||
402 | /** Destructor for ObjectArrayOf. */ | |
403 | ~ObjectArrayOf() | |
404 | { | |
405 | for (uint i=0; i<size; i++) | |
406 | delete array[i]; | |
407 | delete[] array; | |
408 | } | |
409 | ||
410 | /** Index operator for ObjectArrayOf. This indexes into the ObjectArrayOf | |
411 | * and returns the Object instance at the specified index. */ | |
412 | T &operator[](uint i) { assert(i < size); return *array[i]; } | |
413 | ||
414 | private: | |
415 | T **array; | |
416 | uint size; | |
417 | }; | |
418 | ||
419 | /** @} */ | |
420 | ||
421 | #endif |