crashanalysercmd/Libraries/Engine/CrashDebuggerLib/Structures/Thread/DThread.cs
changeset 0 818e61de6cd1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/crashanalysercmd/Libraries/Engine/CrashDebuggerLib/Structures/Thread/DThread.cs	Thu Feb 11 15:50:58 2010 +0200
@@ -0,0 +1,353 @@
+/*
+* Copyright (c) 2004-2008 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: 
+*
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using CrashDebuggerLib.Structures.Common;
+using CrashDebuggerLib.Structures.KernelObjects;
+using CrashDebuggerLib.Structures.Process;
+using CrashDebuggerLib.Structures.NThread;
+using SymbianStructuresLib.Debug.Symbols;
+
+namespace CrashDebuggerLib.Structures.Thread
+{
+    public class DThread : DObject
+    {
+        #region Enumerations
+        [System.ComponentModel.TypeConverter( typeof( SymbianParserLib.TypeConverters.SymbianEnumConverter ) )]
+        public enum TThreadState
+        {
+            EUnknown = -1,
+            ECreated = 0,
+            EDead,
+            EReady,
+            EWaitSemaphore,
+            EWaitSemaphoreSuspended,
+            EWaitMutex,
+            EWaitMutexSuspended,
+            EHoldMutexPending,
+            EWaitCondVar,
+            EWaitCondVarSuspended,
+        }
+
+        [Flags, System.ComponentModel.TypeConverter( typeof( SymbianParserLib.TypeConverters.SymbianEnumConverter ) )]
+        public enum TThreadFlags
+        {
+            EThreadFlagNone                 = 0x00000000,
+            EThreadFlagProcessCritical		= 0x00000001,	// thread panic panics process
+            EThreadFlagProcessPermanent		= 0x00000002,	// thread exit of any kind causes process to exit (=main)
+            EThreadFlagSystemCritical		= 0x00000004,	// thread panic reboots entire system
+            EThreadFlagSystemPermanent		= 0x00000008,	// thread exit of any kind reboots entire system
+            EThreadFlagOriginal				= 0x00000010,
+            EThreadFlagLastChance			= 0x00000020,
+            EThreadFlagRealtime				= 0x00000040,	// thread will be panicked when using some non-realtime functions
+            EThreadFlagRealtimeTest			= 0x00000080	// non-realtime functions only warn rather than panic
+        }
+
+        public enum TThreadWaitType
+        {
+            EThreadWaitingUnknown = 0,
+            EThreadWaitingReady,
+            EThreadWaitingOnSemaphore,
+            EThreadWaitingOnMutex,
+            EThreadWaitingOnDfc,
+            EThreadWaitingOnResumption,
+            EThreadWaitingOnRequestSemaphore,
+            EThreadWaitingOnRequestSemaphoreInsideSchedulerWaitLoop
+        }
+        #endregion
+
+        #region Constructors
+        public DThread( CrashDebuggerInfo aCrashDebugger )
+            : base( aCrashDebugger, TObjectType.EThread )
+        {
+            iNThread = new CrashDebuggerLib.Structures.NThread.NThread( aCrashDebugger, this );
+            iStackInfoSupervisor = new ThreadStackInfo( aCrashDebugger, this, ThreadStackInfo.TType.ETypeSupervisor );
+            iStackInfoUser = new ThreadStackInfo( aCrashDebugger, this, ThreadStackInfo.TType.ETypeUser );
+        }
+        #endregion
+
+        #region API
+        #endregion
+
+        #region Properties
+        public TThreadState MState
+        {
+            get { return iState; }
+            set { iState = value; }
+        }
+
+        public uint WaitObj
+        {
+            get { return iStateWaitObjectAddress; }
+            set { iStateWaitObjectAddress = value; }
+        }
+
+        public TThreadFlags Flags
+        {
+            get { return iFlags; }
+            set { iFlags = value; }
+        }
+
+        public uint Handles
+        {
+            get { return iHandles; }
+            set { iHandles = value; }
+        }
+
+        public long Id
+        {
+            get { return iId; }
+            set { iId = value; }
+        }
+
+        public ThreadAllocatorInfo AllocatorInfo
+        {
+            get { return iAllocatorInfo; }
+        }
+
+        public uint Frame
+        {
+            get { return iFrame; }
+            set { iFrame = value; }
+        }
+
+        public ThreadPriorities Priorities
+        {
+            get { return iPriorities; }
+        }
+
+        public ExitInfo ExitInfo
+        {
+            get { return iExitInfo; }
+        }
+
+        public ThreadStackInfo StackInfoUser
+        {
+            get { return iStackInfoUser; }
+        }
+
+        public ThreadStackInfo StackInfoSupervisor
+        {
+            get { return iStackInfoSupervisor; }
+        }
+
+        public ThreadHandlers Handlers
+        {
+            get { return iHandlers; }
+        }
+
+        public ThreadTemporaries Temporaries
+        {
+            get { return iTemporaries; }
+        }
+
+        public uint IpcCount
+        {
+            get { return iIpcCount; }
+            set { iIpcCount = value; }
+        }
+
+        public DProcess OwningProcess
+        {
+            get
+            {
+                DProcess ret = null;
+                //
+                DObject owner = Owner;
+                if ( owner != null && owner is DProcess )
+                {
+                    ret = (DProcess) owner;
+                }
+                //
+                return ret;
+            }
+        }
+
+        public NThread.NThread NThread
+        {
+            get { return iNThread; }
+        }
+
+        public bool HasActiveScheduler
+        {
+            get
+            {
+                return ( iHandlers.ActiveScheduler != 0 );
+            }
+        }
+
+        public TThreadWaitType WaitType
+        {
+            get
+            {
+                TThreadWaitType waitType = TThreadWaitType.EThreadWaitingUnknown;
+                //
+                if ( NThread.NState == CrashDebuggerLib.Structures.NThread.NThread.TNThreadState.EWaitDfc )
+                {
+                    waitType = TThreadWaitType.EThreadWaitingOnDfc;
+                }
+                else if ( NThread.NState == CrashDebuggerLib.Structures.NThread.NThread.TNThreadState.EReady )
+                {
+                    waitType = TThreadWaitType.EThreadWaitingReady;
+                }
+                else if ( NThread.NState == CrashDebuggerLib.Structures.NThread.NThread.TNThreadState.ESuspended )
+                {
+                    waitType = TThreadWaitType.EThreadWaitingOnResumption;
+                }
+                else if ( NThread.NState == CrashDebuggerLib.Structures.NThread.NThread.TNThreadState.EBlocked )
+                {
+                    bool blockdOnSemaphore = IsBlockedOnSemaphore;
+                    if ( blockdOnSemaphore )
+                    {
+                        waitType = TThreadWaitType.EThreadWaitingOnSemaphore;
+                    }
+                }
+                else if ( NThread.NState == CrashDebuggerLib.Structures.NThread.NThread.TNThreadState.EWaitFastSemaphore )
+                {
+                    // Check that the fast semaphore is definitely the NThread's request semaphore.
+                    uint nThreadRequestSemaphoreAddress = NThread.RequestSemaphoreAddress;
+                    if ( NThread.WaitObj != 0 && NThread.WaitObj == nThreadRequestSemaphoreAddress )
+                    {
+                        CrashDebuggerLib.Structures.NThread.NThread.TWaitType nThreadWaitType = NThread.WaitType;
+                        //
+                        if ( nThreadWaitType == CrashDebuggerLib.Structures.NThread.NThread.TWaitType.EWaitTypeUserWaitForAnyRequest )
+                        {
+                            if ( HasActiveScheduler )
+                            {
+                                waitType = TThreadWaitType.EThreadWaitingOnRequestSemaphoreInsideSchedulerWaitLoop;
+                            }
+                            else
+                            {
+                                waitType = TThreadWaitType.EThreadWaitingOnRequestSemaphore;
+                            }
+                        }
+                        else if ( nThreadWaitType == CrashDebuggerLib.Structures.NThread.NThread.TWaitType.EWaitTypeUserWaitForRequest )
+                        {
+                            waitType = TThreadWaitType.EThreadWaitingOnRequestSemaphore;
+                        }
+                    }
+                }
+                //
+                return waitType;
+            }
+        }
+
+        public bool IsUserThread
+        {
+            get
+            {
+                bool ret = false;
+                //
+                DProcess parent = OwningProcess;
+                if ( parent != null )
+                {
+                    string name = parent.Name.ToLower();
+                    ret = ( name != Platform.ProcessNames.KKernel.ToLower() );
+                }
+                //
+                return ret;
+            }
+        }
+
+        public bool IsCurrent
+        {
+            get
+            {
+                bool ret = CrashDebugger.IsCurrentThread( this );
+                return ret;
+            }
+        }
+        #endregion
+
+        #region Internal methods
+        private bool IsBlockedOnSemaphore
+        {
+            get
+            {
+                bool ret = false;
+                //
+                if ( NThread.NState == CrashDebuggerLib.Structures.NThread.NThread.TNThreadState.EBlocked )
+                {
+                    Register.RegisterEntry linkReg = NThread.Registers[ "R14_USR" ];
+                    if ( linkReg.Symbol != null )
+                    {
+                        string symbolText = linkReg.Symbol.Name;
+                        if ( symbolText.Contains( "RSemaphore::Wait" ) || symbolText.Contains( "RCriticalSection::Wait" ) )
+                        {
+                            ret = true;
+                        }
+                        else if ( symbolText.Contains( "Exec::SemaphoreWait" ) )
+                        {
+                            ret = true;
+                        }
+                    }
+                }
+                //
+                return ret;
+            }
+        }
+        #endregion
+
+        #region Internal constants
+        #endregion
+
+        #region From DBase
+        public override string ToClipboard()
+        {
+            StringBuilder ret = new StringBuilder();
+            //
+            ret.AppendLine( base.ToClipboard() );
+            ret.AppendFormat( "MState: {0}, Id: {1}, ExitInfo: {2}" + System.Environment.NewLine, MState, Id, ExitInfo );
+            ret.AppendLine( iNThread.ToClipboard() );
+            ret.AppendLine( iStackInfoUser.ToClipboard() );
+            ret.AppendLine( iStackInfoSupervisor.ToClipboard() );
+            //
+            return ret.ToString();
+        }
+        #endregion
+
+        #region From System.Object
+        public override string ToString()
+        {
+            return base.ToString();
+        }
+        #endregion
+
+        #region Data members
+        private readonly NThread.NThread iNThread;
+        private readonly ThreadStackInfo iStackInfoSupervisor;
+        private readonly ThreadStackInfo iStackInfoUser;
+
+        private TThreadState iState = TThreadState.EUnknown;
+        private TThreadFlags iFlags = TThreadFlags.EThreadFlagNone;
+        
+        private uint iStateWaitObjectAddress = 0;
+        private uint iHandles = 0;
+        private long iId = 0;
+        private uint iFrame = 0;
+        private uint iIpcCount = 0;
+
+        private ThreadAllocatorInfo iAllocatorInfo = new ThreadAllocatorInfo();
+        private ThreadPriorities iPriorities = new ThreadPriorities();
+        private ExitInfo iExitInfo = new ExitInfo();
+        private ThreadHandlers iHandlers = new ThreadHandlers();
+        private ThreadTemporaries iTemporaries = new ThreadTemporaries();
+        #endregion
+    }
+}
\ No newline at end of file