CallStack.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2005 Palmsource, Inc.
00003  * 
00004  * This software is licensed as described in the file LICENSE, which
00005  * you should have received as part of this distribution. The terms
00006  * are also available at http://www.openbinder.org/license.html.
00007  * 
00008  * This software consists of voluntary contributions made by many
00009  * individuals. For the exact contribution history, see the revision
00010  * history and logs, available at http://www.openbinder.org
00011  */
00012 
00013 #ifndef _SUPPORT_CALLSTACK_H
00014 #define _SUPPORT_CALLSTACK_H
00015 
00021 #include <support/ITextStream.h>
00022 #include <support/SupportDefs.h>
00023 #include <support/Vector.h>
00024 #include <support/KeyedVector.h>
00025 #include <support/Locker.h>
00026 
00027 #if _SUPPORTS_NAMESPACE
00028 namespace palmos {
00029 namespace support {
00030 #endif
00031 
00036 class SCallTree;
00037 
00038 typedef int32_t (*b_demangle_func)( const char *mangled_name,
00039                                     char *unmangled_name,
00040                                     size_t buffersize);
00041 
00042 enum {
00043     B_CALLSTACK_DEPTH       = 32
00044 };
00045 
00047 class SCallStack {
00048 public:
00049                             SCallStack();
00050                             SCallStack(const SCallStack& o);
00051                             SCallStack(const SValue &value);
00052     virtual                 ~SCallStack();
00053                             
00054             SValue          AsValue() const;
00055                             
00056             SCallStack      &operator=(const SCallStack& o);
00057             
00058             void            Update(int32_t ignoreDepth=0, int32_t maxDepth=B_CALLSTACK_DEPTH);
00059             
00060             intptr_t        AddressAt(int32_t level) const;
00061             void            SPrint(char *buffer) const;
00062             void            Print(const sptr<ITextOutput>& io) const;
00063             void            LongPrint(const sptr<ITextOutput>& io, b_demangle_func demangler=NULL) const;
00064         
00065             bool            operator==(const SCallStack& o) const;
00066     inline  bool            operator!=(const SCallStack& o) const   { return !(*this == o); }
00067     
00068             int32_t         Compare(const SCallStack& o) const;
00069     inline  bool            operator<(const SCallStack& o) const    { return Compare(o) < 0; }
00070     inline  bool            operator<=(const SCallStack& o) const   { return Compare(o) <= 0; }
00071     inline  bool            operator>=(const SCallStack& o) const   { return Compare(o) >= 0; }
00072     inline  bool            operator>(const SCallStack& o) const    { return Compare(o) > 0; }
00073     
00074 private:
00075             intptr_t        GetCallerAddress(int32_t level) const;
00076 
00077             intptr_t        m_caller[B_CALLSTACK_DEPTH];
00078             int32_t         _reserved[2];
00079 };
00080 
00081 inline const sptr<ITextOutput>& operator<<(const sptr<ITextOutput>& io, const SCallStack& stack)
00082 {
00083     stack.Print(io);
00084     return io;
00085 }
00086 
00087 class SCallTreeNode {
00088 public:
00089                             SCallTreeNode();
00090     virtual                 ~SCallTreeNode();
00091     
00092             void            PruneNode();
00093             void            ShortReport(const sptr<ITextOutput>& io);
00094             void            LongReport(const sptr<ITextOutput>& io, b_demangle_func demangler=NULL,
00095                                        char *buffer=NULL, int32_t bufferSize=0);
00096     
00097 private:
00098                             SCallTreeNode(const SCallTreeNode& o);
00099             SCallTreeNode&  operator=(const SCallTreeNode& o);
00100     
00101     friend  class                   SCallTree;
00102             
00103             intptr_t                addr;
00104             int32_t                 count;
00105             SCallTreeNode *         higher;
00106             SCallTreeNode *         lower;
00107             SCallTreeNode *         parent;
00108             SVector<SCallTreeNode*> branches;
00109 };
00110 
00111 class SCallTree : public SCallTreeNode {
00112 public:
00113                             SCallTree(const char *name);
00114     virtual                 ~SCallTree();
00115     
00116             void            Prune();
00117             void            AddToTree(SCallStack *stack, const sptr<ITextOutput>& io);
00118             void            Report(const sptr<ITextOutput>& io, int32_t count, bool longReport=false);
00119 
00120 private:
00121                             SCallTree(const SCallTree& o);
00122             SCallTree&      operator=(const SCallTree& o);
00123             
00124             SCallTreeNode*  highest;
00125             SCallTreeNode*  lowest;
00126 };
00127 
00128 // DON'T USE THIS CLASS IN LOCK DEBUGGING!
00129 class SStackCounter
00130 {
00131 public:
00132                             SStackCounter();
00133     virtual                 ~SStackCounter();
00134 
00135             void            Update(int32_t ignoreDepth=0, int32_t maxDepth=B_CALLSTACK_DEPTH);
00136 
00137             void            Reset();
00138             void            Print(const sptr<ITextOutput>& io, size_t maxItems=-1) const;
00139             void            LongPrint(const sptr<ITextOutput>& io, size_t maxItems=-1, b_demangle_func demangler=NULL) const;
00140             
00141             size_t          TotalCount() const;
00142             
00143 private:
00144     struct stack_info {
00145         size_t count;
00146     };
00147     mutable SLocker                         m_lock;
00148     SKeyedVector<SCallStack, stack_info>    m_data;
00149     size_t                                  m_totalCount;
00150 };
00151 
00152 
00155 #if _SUPPORTS_NAMESPACE
00156 } } // namespace palmos::support
00157 #endif
00158 
00159 #endif /* _SUPPORT_CALLSTACK_H */