eventlog.hpp

Go to the documentation of this file.
00001 /* Copyright 1994 - 1996 LongView Technologies L.L.C. $Revision: 1.7 $ */
00002 /* Copyright (c) 2006, Sun Microsystems, Inc.
00003 All rights reserved.
00004 
00005 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the 
00006 following conditions are met:
00007 
00008     * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
00009     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 
00010           disclaimer in the documentation and/or other materials provided with the distribution.
00011     * Neither the name of Sun Microsystems nor the names of its contributors may be used to endorse or promote products derived 
00012           from this software without specific prior written permission.
00013 
00014 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT 
00015 NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 
00016 THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
00017 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
00018 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
00019 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
00020 
00021 
00022 */
00023 
00024 // The EL_Event log is used for debugging; it is a circular buffer containing
00025 // the last N events.  An EL_Event is represented by an identifying string
00026 // and up to EVENT_PARAMS parameters.
00027 
00028 const int EVENT_PARAMS = 3;       // number of params per EL_Event
00029 
00030 // helper macros
00031 
00032 #define LOG_EVENT(name)           eventLog->log(name)
00033 #define LOG_EVENT1(name,p1)       eventLog->log(name, (void*)(p1))
00034 #define LOG_EVENT2(name,p1,p2)    eventLog->log(name, (void*)(p1), (void*)(p2))
00035 #define LOG_EVENT3(name,p1,p2,p3) eventLog->log(name, (void*)(p1), (void*)(p2), (void*)(p3))
00036 
00037 enum EL_EventStatus { starting, ending, atomic };
00038 
00039 struct EL_Event /* no superclass - never allocated individually */ {       
00040   char* name;                     // in printf format
00041   EL_EventStatus status;          // for nested events
00042   void* args[EVENT_PARAMS];
00043 };
00044 
00045 
00046 struct EventLog : public CHeapObj {   
00047   EL_Event* buf;                  // event buffer
00048   EL_Event* bufEnd;
00049   EL_Event* next;                 // where the next entry will go
00050   int  nesting;                   // current nesting depth
00051 
00052   EventLog();
00053   void   init();
00054 
00055   EL_Event* nextEvent(EL_Event* e, EL_Event* start, EL_Event* end) {
00056     if (e + 1 == end) return start; else return e + 1; }
00057   EL_Event* prevEvent(EL_Event* e, EL_Event* start, EL_Event* end) {
00058     if (e == start) return end - 1; else return e - 1; }
00059   void   inc()          { next = nextEvent(next, buf, bufEnd); }
00060 
00061   void   log(EL_Event* e)  { *next = *e; inc(); }
00062   void   log(char* name) {
00063     next->name = name; next->status = atomic;
00064     inc(); }
00065   void   log(char* name, void* p1) {
00066     next->name = name; next->status = atomic;
00067     next->args[0] = p1; inc(); }
00068   void   log(char* name, void* p1, void* p2) {
00069     next->name = name; next->status = atomic;
00070     next->args[0] = p1; next->args[1] = p2; inc(); }
00071   void   log(char* name, void* p1, void* p2, void* p3) {
00072     next->name = name; next->status = atomic;
00073     next->args[0] = p1; next->args[1] = p2; next->args[2] = p3; inc(); }
00074   
00075   void   resize();                // resize buffer
00076   
00077   void   print() { printPartial(bufEnd - buf); }
00078   void   printPartial(int n);
00079 };
00080 
00081 extern EventLog* eventLog;
00082 
00083 class EventMarker : StackObj {    // for events which have a duration
00084  public:
00085   EL_Event event;
00086   EL_Event* here;
00087 
00088   EventMarker(char* n)                                  { init(n, 0, 0, 0); }
00089   EventMarker(char* n, void* p1)                        { init(n, p1, 0, 0); }
00090   EventMarker(char* n, void* p1, void* p2)              { init(n, p1, p2, 0); }
00091   EventMarker(char* n, void* p1, void* p2, void* p3)    { init(n, p1, p2, p3);}
00092 
00093   void init(char* n, void* p1, void* p2, void* p3) {
00094     here = eventLog->next;
00095     eventLog->log(n, p1, p2, p3);
00096     here->status = starting; 
00097     event = *here;
00098     eventLog->nesting++;
00099   }
00100   ~EventMarker() {
00101     eventLog->nesting--;
00102     // optimization to make log less verbose; this isn't totally failproof
00103     // but that's ok
00104     if (here == eventLog->next - 1) {
00105       *here = event;
00106       here->status = atomic;       // nothing happened inbetween
00107     } else {
00108       event.status = ending;
00109       eventLog->log(&event);
00110     }
00111   }
00112 };

Generated on Mon Oct 9 13:37:09 2006 for Strongtalk VM by  doxygen 1.4.7