public void Execute(State.ExecutionContext context, ulong address) { if (Interlocked.Increment(ref _threadCount) == 1) { Thread backgroundTranslatorThread = new Thread(TranslateQueuedSubs) { Name = "CPU.BackgroundTranslatorThread", Priority = ThreadPriority.Lowest }; backgroundTranslatorThread.Start(); } Statistics.InitializeTimer(); NativeInterface.RegisterThread(context, _memory); do { address = ExecuteSingle(context, address); }while (context.Running && (address & ~1UL) != 0); NativeInterface.UnregisterThread(); if (Interlocked.Decrement(ref _threadCount) == 0) { _backgroundTranslatorEvent.Set(); } }
public ThreadContext(State.ExecutionContext context, IMemoryManager memory, Translator translator) { Context = context; Memory = memory; Translator = translator; ExclusiveAddress = ulong.MaxValue; }
public ulong ExecuteSingle(State.ExecutionContext context, ulong address) { TranslatedFunction func = GetOrTranslate(address, context.ExecutionMode); Statistics.StartTimer(); ulong nextAddr = func.Execute(context); Statistics.StopTimer(address); return(nextAddr); }
public void Execute(State.ExecutionContext context, ulong address) { if (Interlocked.Increment(ref _threadCount) == 1) { IsReadyForTranslation.WaitOne(); if (Ptc.State == PtcState.Enabled) { Ptc.MakeAndSaveTranslations(_funcs, _memory, _jumpTable); } PtcProfiler.Start(); Ptc.Disable(); // Simple heuristic, should be user configurable in future. (1 for 4 core/ht or less, 2 for 6 core+ht etc). // All threads are normal priority except from the last, which just fills as much of the last core as the os lets it with a low priority. // If we only have one rejit thread, it should be normal priority as highCq code is performance critical. // TODO: Use physical cores rather than logical. This only really makes sense for processors with hyperthreading. Requires OS specific code. int unboundedThreadCount = Math.Max(1, (Environment.ProcessorCount - 6) / 3); int threadCount = Math.Min(4, unboundedThreadCount); for (int i = 0; i < threadCount; i++) { bool last = i != 0 && i == unboundedThreadCount - 1; Thread backgroundTranslatorThread = new Thread(TranslateStackedSubs) { Name = "CPU.BackgroundTranslatorThread." + i, Priority = last ? ThreadPriority.Lowest : ThreadPriority.Normal }; backgroundTranslatorThread.Start(); } } Statistics.InitializeTimer(); NativeInterface.RegisterThread(context, _memory, this); do { address = ExecuteSingle(context, address); }while (context.Running && (address & ~1UL) != 0); NativeInterface.UnregisterThread(); if (Interlocked.Decrement(ref _threadCount) == 0) { _backgroundTranslatorEvent.Set(); } }
public static void RegisterThread(State.ExecutionContext context, IMemoryManager memory, Translator translator) { _context = new ThreadContext(context, memory, translator); }
public ulong Execute(State.ExecutionContext context) { return(_func(context.NativeContextPtr)); }