/// <summary> /// /// </summary> /// <param name="handle">执行回调</param> /// <param name="sleeptime">0 表示执行一次,否则执行到线程主动停止</param> public MFThread(ThreadHandle handle, int sleeptime = 0) { this.mThreadName = handle.ToString() + iThreadRef.ToString(); this.mSleepTime = sleeptime; this.m_ThreadEvent = handle; iThreadRef++; }
internal static unsafe void FinishInitializeThread() { int threadIndex = initialThread.threadIndex; // Get the GC ready for initialThread Transitions.RuntimeInitialized(); Transitions.ThreadStart(); initialThread.processGcEvent = new AutoResetEvent(false); initialThread.autoEvent = new AutoResetEvent(false); initialThread.joinEvent = new ManualResetEvent(false); initialThread.singleQueueItem = new ThreadQueueItem [1] { new ThreadQueueItem(initialThread) }; // Use CurrentThread to find our initial handle: VTable.Assert(initialThread == CurrentThread); initialThread.threadHandle = ThreadHandle.CurrentThread(); // Instantiate the static variable that needs to be initialized m_LocalDataStoreMgr = new LocalDataStoreMgr(); AddThread(threadIndex); }
//========================================================================= // Spawns off a new thread which will begin executing at the ThreadStart // method on the IThreadable interface passed in the constructor. Once the // thread is dead, it cannot be restarted with another call to Start. // // Exceptions: ThreadStateException if the thread has already been started. //========================================================================= //| <include path='docs/doc[@for="Thread.Start"]/*' /> public void Start() { lock ((Object)this) { if (closing) { throw new ThreadStateException("Cannot start thread when closing"); } ThreadState oldState = threadState; if (oldState != ThreadState.Unstarted) { throw new ThreadStateException("Cannot start thread in state " + oldState); } threadState = ThreadState.Running; // Tell the GC that we have created the thread GC.NewThreadNotification(this, false); ThreadHandle.Start(threadHandle); GC.KeepAlive(this); } }
private void BufferWorkerThreadStart() { int cursor = 0; _bufferWorkerThreadHandle = ThreadHandle.OpenCurrent(ThreadAccess.All); _bufferWorkerThreadReadyEvent.Set(); while (!_terminating) { NtStatus status; KphSsBlockHeader blockHeader; status = _readSemaphore.Wait(true); if (status == NtStatus.Alerted) return; if (_buffer.Size - cursor < Marshal.SizeOf(typeof(KphSsBlockHeader))) cursor = 0; blockHeader = _buffer.ReadStruct<KphSsBlockHeader>(cursor, 0); if (blockHeader.Type == KphSsBlockType.Reset) { cursor = 0; blockHeader = _buffer.ReadStruct<KphSsBlockHeader>(cursor, 0); } if (blockHeader.Type == KphSsBlockType.Event) { var eventBlock = _buffer.ReadStruct<KphSsEventBlock>(cursor, 0); int[] arguments; IntPtr[] stackTrace; arguments = new int[eventBlock.NumberOfArguments]; stackTrace = new IntPtr[eventBlock.TraceCount]; for (int i = 0; i < arguments.Length; i++) arguments[i] = _buffer.ReadInt32(cursor + eventBlock.ArgumentsOffset, i); for (int i = 0; i < stackTrace.Length; i++) stackTrace[i] = _buffer.ReadIntPtr(cursor + eventBlock.TraceOffset, i); SsEvent ssEvent = new SsEvent(); ssEvent.Time = DateTime.FromFileTime(eventBlock.Time); ssEvent.ThreadId = eventBlock.ClientId.ThreadId; ssEvent.ProcessId = eventBlock.ClientId.ProcessId; ssEvent.Arguments = arguments; ssEvent.StackTrace = stackTrace; ssEvent.ArgumentsCopyFailed = (eventBlock.Flags & KphSsEventFlags.CopyArgumentsFailed) == KphSsEventFlags.CopyArgumentsFailed; ssEvent.ArgumentsProbeFailed = (eventBlock.Flags & KphSsEventFlags.ProbeArgumentsFailed) == KphSsEventFlags.ProbeArgumentsFailed; ssEvent.CallNumber = eventBlock.Number; if ((eventBlock.Flags & KphSsEventFlags.UserMode) == KphSsEventFlags.UserMode) ssEvent.Mode = KProcessorMode.UserMode; else ssEvent.Mode = KProcessorMode.KernelMode; if (this.EventBlockReceived != null) this.EventBlockReceived(ssEvent); } else if (blockHeader.Type == KphSsBlockType.Argument) { var argBlock = _buffer.ReadStruct<KphSsArgumentBlock>(cursor, 0); MemoryRegion dataRegion; SsData ssArg = null; dataRegion = new MemoryRegion(_buffer, cursor + KphSsArgumentBlock.DataOffset); switch (argBlock.Type) { case KphSsArgumentType.Int8: { SsSimple simpleArg = new SsSimple(); simpleArg.Argument = argBlock.Data.Int8; simpleArg.Type = typeof(Byte); ssArg = simpleArg; } break; case KphSsArgumentType.Int16: { SsSimple simpleArg = new SsSimple(); simpleArg.Argument = argBlock.Data.Int16; simpleArg.Type = typeof(Int16); ssArg = simpleArg; } break; case KphSsArgumentType.Int32: { SsSimple simpleArg = new SsSimple(); simpleArg.Argument = argBlock.Data.Int32; simpleArg.Type = typeof(Int32); ssArg = simpleArg; } break; case KphSsArgumentType.Int64: { SsSimple simpleArg = new SsSimple(); simpleArg.Argument = argBlock.Data.Int64; simpleArg.Type = typeof(Int64); ssArg = simpleArg; } break; case KphSsArgumentType.Handle: { ssArg = new SsHandle(dataRegion); } break; case KphSsArgumentType.UnicodeString: { ssArg = new SsUnicodeString(dataRegion); } break; case KphSsArgumentType.ObjectAttributes: { ssArg = new SsObjectAttributes(dataRegion); } break; case KphSsArgumentType.ClientId: { ssArg = new SsClientId(dataRegion); } break; } ssArg.Index = argBlock.Index; if (ssArg != null) { if (this.ArgumentBlockReceived != null) this.ArgumentBlockReceived(ssArg); } } cursor += blockHeader.Size; _writeSemaphore.Release(); } }
private static extern void InformThreadNameChange(ThreadHandle t, string name, int len);
private static unsafe partial void StartInternal(ThreadHandle t, int stackSize, int priority, char *pThreadName);
private static partial void InformThreadNameChange(ThreadHandle t, string?name, int len);
private void WaiterThreadStart() { ISynchronizable[] waitObjects = null; // Open a handle to the current thread. _threadHandle = ThreadHandle.OpenCurrent(ThreadAccess.Alert); // Signal that the thread has been initialized. _threadInitializedEvent.Set(); while (!_terminating) { bool doWait; lock (_waitObjects) { // Check if we have any objects to wait for. If we do, use WaitAny. // Otherwise, wait forever (alertably). if (_waitObjects.Count > 0) { waitObjects = _waitObjects.ToArray(); doWait = true; } else { doWait = false; } } NtStatus waitStatus; if (doWait) { try { // Wait for the objects, (almost) forever. waitStatus = NativeHandle.WaitAny(waitObjects, true, long.MinValue, false); } catch (WindowsException) { // We probably got Access denied on one of the objects. // We can't do anything about this, so just wait forever. waitStatus = ThreadHandle.Sleep(true, long.MinValue, false); } } else { // Wait forever. waitStatus = ThreadHandle.Sleep(true, long.MinValue, false); } if (waitStatus == NtStatus.Alerted) { // The wait was changed. Go back to refresh the wait objects array. // The thread is also alerted to notify that the thread should terminate. continue; } else if (waitStatus >= NtStatus.Wait0 && waitStatus <= NtStatus.Wait63) { // One of the objects was signaled. ISynchronizable signaledObject = waitObjects[(int)(waitStatus - NtStatus.Wait0)]; // Remove the object now that it is signaled. lock (_waitObjects) { // Just in case someone already removed the object. if (_waitObjects.Contains(signaledObject)) _waitObjects.Remove(signaledObject); } // Call the object-signaled event. OnObjectSignaled(signaledObject); // Balance the threads (which may involve terminating the current one). _owner.BalanceWaiterThreads(); } } }
private void TryEnterLock( ThreadUnsafePolicy policy, MethodExecutionArgs args ) { object syncObject; syncObject = GetSyncObject(policy, args.Instance, args.Method.DeclaringType); if ( runningThreadSafeMethods != null && runningThreadSafeMethods.ContainsKey( syncObject ) ) return; ThreadHandle currentThread = new ThreadHandle( Thread.CurrentThread ); ThreadHandle actualThread = locks.AddOrUpdate( syncObject, o => currentThread, ( o, thread ) => { if ( thread.Thread != currentThread.Thread ) throw new ThreadUnsafeException(ThreadUnsafeErrorCode.SimultaneousAccess); // Same thread, but different ThreadHandle: we are in a nested call on the same thread. return thread; } ); if ( actualThread == currentThread ) { args.MethodExecutionTag = syncObject; } }
//public IntPtr AddNumberRule(FilterType filterType, int number) //{ // return KProcessHacker.Instance.SsAddNumberRule( // _ruleSetEntryHandle, // filterType.ToKphSs(), // number // ); //} //public IntPtr AddPreviousModeRule(FilterType filterType, KProcessorMode previousMode) //{ // return KProcessHacker.Instance.SsAddPreviousModeRule( // _ruleSetEntryHandle, // filterType.ToKphSs(), // previousMode // ); //} //public IntPtr AddProcessIdRule(FilterType filterType, int pid) //{ // return KProcessHacker.Instance.SsAddProcessIdRule( // _ruleSetEntryHandle, // filterType.ToKphSs(), // pid.ToIntPtr() // ); //} //public IntPtr AddThreadIdRule(FilterType filterType, int tid) //{ // return KProcessHacker.Instance.SsAddProcessIdRule( // _ruleSetEntryHandle, // filterType.ToKphSs(), // tid.ToIntPtr() // ); //} private void BufferWorkerThreadStart() { // Open a handle to the current thread so other functions // can alert us. _bufferWorkerThreadHandle = ThreadHandle.OpenCurrent(ThreadAccess.All); // We're ready. _bufferWorkerThreadReadyEvent.Set(); while (!_terminating) { NtStatus status; KphSsBlockHeader blockHeader; // Wait for a block to read (enable alerting so we can // be interrupted if someone wants us to stop). status = _readSemaphore.Wait(true); // Did we get alerted? if (status == NtStatus.Alerted) return; // Check if we have an implicit cursor reset. if (_buffer.Size - _cursor < KphSsBlockHeader.SizeOf) _cursor = 0; // Read the block header. blockHeader = _buffer.ReadStruct<KphSsBlockHeader>(_cursor, KphSsBlockHeader.SizeOf, 0); // Check if we have an explicit cursor reset. if (blockHeader.Type == KphSsBlockType.Reset) { _cursor = 0; blockHeader = _buffer.ReadStruct<KphSsBlockHeader>(_cursor, KphSsBlockHeader.SizeOf, 0); } // Process the block. switch (blockHeader.Type) { case KphSsBlockType.Event: if (this.EventBlockReceived != null) this.EventBlockReceived(ReadEventBlock(new MemoryRegion(this._buffer, this._cursor))); if (this.RawEventBlockReceived != null) this.RawEventBlockReceived(new MemoryRegion(this._buffer, this._cursor)); break; case KphSsBlockType.Argument: if (this.ArgumentBlockReceived != null) this.ArgumentBlockReceived(ReadArgumentBlock(new MemoryRegion(this._buffer, this._cursor))); if (this.RawArgumentBlockReceived != null) this.RawArgumentBlockReceived(new MemoryRegion(this._buffer, this._cursor)); break; } // Advance the cursor. _cursor += blockHeader.Size; // Signal that a buffer block is available for writing. _writeSemaphore.Release(); } }
//| <include path='docs/doc[@for="Thread.Sleep"]/*' /> public static void Sleep(TimeSpan timeout) { ThreadHandle.Sleep(timeout); }
//========================================================================= // Creates a new Thread object which will begin execution at // start.ThreadStart on a new thread when the Start method is called. // // Exceptions: ArgumentNullException if start == null. //========================================================================= //| <include path='docs/doc[@for="Thread.Thread"]/*' /> public unsafe Thread(ThreadStart start) { Tracing.Log(Tracing.Audit, "Application Thread()"); if (start == null) { throw new ArgumentNullException("start"); } threadIndex = -1; threadState = ThreadState.Unstarted; threadStart = start; // Create the event for the thread to wait upon autoEvent = new AutoResetEvent(false); joinEvent = new ManualResetEvent(false); processGcEvent = new AutoResetEvent(false); singleQueueItem = new ThreadQueueItem [1] { new ThreadQueueItem(this) }; // Find a usable entry in the thread table // Disable local preemption while holding the lock. This might also be a // the property of the lock bool disabled = Processor.DisableLocalPreemption(); Thread.threadTableLock.Acquire(CurrentThread); try { for (int i = 0; i < threadTable.Length; i++) { int index = (threadIndexGenerator + i) % threadTable.Length; if (threadTable[index] == null) { threadTable[index] = this; this.threadIndex = index; threadIndexGenerator = index + 1; // NB: We call this once, afterwards the GC visitor calls it. break; } } } finally { Thread.threadTableLock.Release(CurrentThread); Processor.RestoreLocalPreemption(disabled); } VTable.Assert(threadIndex >= 0, "Out of thread slots!"); //MemoryBarrier(); // Must check closing after being insert into table to avoid race condition. if (closing) { threadState = ThreadState.Stopped; joinEvent.Set(); Tracing.Log(Tracing.Warning, "Aborting: Runtime closing."); return; } ThreadHandle handleOnStack; UIntPtr threadContext; if (!ThreadHandle.Create(threadIndex, new ContainerHandle(), out handleOnStack, out threadContext)) { Tracing.Log(Tracing.Warning, "Aborting: ThreadHandle.Create failed."); threadState = ThreadState.Stopped; joinEvent.Set(); return; } this.threadHandle = handleOnStack; this.context = (ThreadContext *)threadContext; this.context->threadIndex = unchecked ((ushort)threadIndex); this.context->UpdateAfterGC(this); }
public static void Yield() { ThreadHandle.Yield(); }
private void BufferWorkerThreadStart() { int cursor = 0; // Open a handle to the current thread so other functions // can alert us. _bufferWorkerThreadHandle = ThreadHandle.OpenCurrent(ThreadAccess.All); // We're ready. _bufferWorkerThreadReadyEvent.Set(); while (!_terminating) { NtStatus status; KphSsBlockHeader blockHeader; // Wait for a block to read (enable alerting so we can // be interrupted if someone wants us to stop). status = _readSemaphore.Wait(true); // Did we get alerted? if (status == NtStatus.Alerted) return; // Check if we have an implicit cursor reset. if (_buffer.Size - cursor < Marshal.SizeOf(typeof(KphSsBlockHeader))) cursor = 0; // Read the block header. blockHeader = _buffer.ReadStruct<KphSsBlockHeader>(cursor, 0); // Check if we have an explicit cursor reset. if (blockHeader.Type == KphSsBlockType.Reset) { cursor = 0; blockHeader = _buffer.ReadStruct<KphSsBlockHeader>(cursor, 0); } // Process the block. if (blockHeader.Type == KphSsBlockType.Event) { var eventBlock = _buffer.ReadStruct<KphSsEventBlock>(cursor, 0); int[] arguments; IntPtr[] stackTrace; // Reconstruct the argument and stack trace arrays. arguments = new int[eventBlock.NumberOfArguments]; stackTrace = new IntPtr[eventBlock.TraceCount]; for (int i = 0; i < arguments.Length; i++) arguments[i] = _buffer.ReadInt32(cursor + eventBlock.ArgumentsOffset, i); for (int i = 0; i < stackTrace.Length; i++) stackTrace[i] = _buffer.ReadIntPtr(cursor + eventBlock.TraceOffset, i); // Create an event object. SsEvent ssEvent = new SsEvent(); // Basic information ssEvent.Time = DateTime.FromFileTime(eventBlock.Time); ssEvent.ThreadId = eventBlock.ClientId.ThreadId; ssEvent.ProcessId = eventBlock.ClientId.ProcessId; ssEvent.Arguments = arguments; ssEvent.StackTrace = stackTrace; // Flags ssEvent.ArgumentsCopyFailed = (eventBlock.Flags & KphSsEventFlags.CopyArgumentsFailed) == KphSsEventFlags.CopyArgumentsFailed; ssEvent.ArgumentsProbeFailed = (eventBlock.Flags & KphSsEventFlags.ProbeArgumentsFailed) == KphSsEventFlags.ProbeArgumentsFailed; ssEvent.CallNumber = eventBlock.Number; if ((eventBlock.Flags & KphSsEventFlags.UserMode) == KphSsEventFlags.UserMode) ssEvent.Mode = KProcessorMode.UserMode; else ssEvent.Mode = KProcessorMode.KernelMode; // Raise the event. if (this.EventBlockReceived != null) this.EventBlockReceived(ssEvent); } else if (blockHeader.Type == KphSsBlockType.Argument) { var argBlock = _buffer.ReadStruct<KphSsArgumentBlock>(cursor, 0); MemoryRegion dataRegion; SsData ssArg = null; dataRegion = new MemoryRegion(_buffer, cursor + KphSsArgumentBlock.DataOffset); // Process the argument block based on its type. switch (argBlock.Type) { case KphSsArgumentType.Int8: { SsSimple simpleArg = new SsSimple(); simpleArg.Argument = argBlock.Data.Int8; simpleArg.Type = typeof(Byte); ssArg = simpleArg; } break; case KphSsArgumentType.Int16: { SsSimple simpleArg = new SsSimple(); simpleArg.Argument = argBlock.Data.Int16; simpleArg.Type = typeof(Int16); ssArg = simpleArg; } break; case KphSsArgumentType.Int32: { SsSimple simpleArg = new SsSimple(); simpleArg.Argument = argBlock.Data.Int32; simpleArg.Type = typeof(Int32); ssArg = simpleArg; } break; case KphSsArgumentType.Int64: { SsSimple simpleArg = new SsSimple(); simpleArg.Argument = argBlock.Data.Int64; simpleArg.Type = typeof(Int64); ssArg = simpleArg; } break; case KphSsArgumentType.Handle: { ssArg = new SsHandle(dataRegion); } break; case KphSsArgumentType.UnicodeString: { ssArg = new SsUnicodeString(dataRegion); } break; case KphSsArgumentType.ObjectAttributes: { ssArg = new SsObjectAttributes(dataRegion); } break; case KphSsArgumentType.ClientId: { ssArg = new SsClientId(dataRegion); } break; } ssArg.Index = argBlock.Index; // Raise the event. if (ssArg != null) { if (this.ArgumentBlockReceived != null) this.ArgumentBlockReceived(ssArg); } } // Advance the cursor. cursor += blockHeader.Size; // Signal that a buffer block is available for writing. _writeSemaphore.Release(); } }