public KThread(Kernel kernel, KModule module, KPartition partition, string name, uint entryAddress, int priority, KThreadAttributes attributes, uint stackSize) { Debug.Assert(partition != null); Kernel = kernel; Name = name; EntryAddress = entryAddress; InitialPriority = priority; Priority = priority; Attributes = attributes; Module = module; State = KThreadState.Stopped; ExitWaiters = new FastLinkedList <KThread>(); NotifiedCallbacks = new FastLinkedList <KCallback>(); //if( stackSize < 65535 ) //{ // Log.WriteLine( Verbosity.Normal, Feature.Bios, "KThread: attempt to allocate thread with a stack of {0} - forcing up to the minimum of 64K", stackSize ); // stackSize = 65535; //} RunClocks = 0; InterruptPreemptionCount = 0; ThreadPreemptionCount = 0; Partition = partition; StackBlock = partition.Allocate(string.Format("Thread '{0}' Stack", name), KAllocType.High, 0, stackSize); Debug.Assert(StackBlock != null); TlsBlock = partition.Allocate(string.Format("Thread '{0}' TLS", name), KAllocType.High, 0, 0x4000); // 16k of thread local storage --- enough? Debug.Assert(TlsBlock != null); }
public void Start(uint argumentsLength, uint argumentsPointer) { uint[] registers = new uint[32]; registers[4] = argumentsLength; registers[5] = argumentsPointer; registers[6] = 0; if (TlsBlock != null) { registers[26] = TlsBlock.Address; // TLS } else { registers[26] = 0; } registers[28] = GlobalPointer; // gp - set by cpu? registers[29] = StackBlock.UpperBound; ContextID = Kernel.Cpu.AllocateContextStorage(EntryAddress, registers); State = KThreadState.Ready; if (Diag.IsAttached == true) { Breakpoint bp = new Breakpoint(Diag.Instance.Client.AllocateID(), BreakpointType.Stepping, this.EntryAddress); Diag.Instance.CpuHook.AddBreakpoint(bp); } Kernel.Threads.Add(this); this.AddToSchedule(); }
public bool CheckCallbacks( KThread thread ) { Debug.Assert( thread != null ); if( thread.NotifiedCallbacks.Count == 0 ) return false; Debug.Assert( _runningUserCall == false ); Debug.Assert( _runningCallback == null ); if( this.ActiveThread != thread ) { Debug.Assert( ( thread.State == KThreadState.Waiting ) || ( thread.State == KThreadState.WaitSuspended ) ); _oldThread = this.ActiveThread; this.ActiveThread = thread; } _oldThreadState = thread.State; thread.State = KThreadState.Ready; KCallback callback = thread.NotifiedCallbacks.Dequeue(); Log.WriteLine( Verbosity.Verbose, Feature.Bios, "Kernel::CheckCallbacks: issuing callback {0} on thread {1} (thread was {2})", callback.UID.ToString( "X" ), this.ActiveThread.UID.ToString( "X" ), _oldThread.UID.ToString( "X" ) ); _runningCallback = callback; // Format is arg1, arg2, commonAddress // arg1 = passed during notify // arg2 is passed during notify and given to use in argument Cpu.MarshalCall( this.ActiveThread.ContextID, callback.Address, new uint[] { callback.NotifyCount, callback.NotifyArguments, callback.CommonAddress }, new MarshalCompleteDelegate( this.CallbackComplete ), 0 ); return true; }
public bool CheckCallbacks(KThread thread) { Debug.Assert(thread != null); if (thread.NotifiedCallbacks.Count == 0) { return(false); } Debug.Assert(_runningUserCall == false); Debug.Assert(_runningCallback == null); if (this.ActiveThread != thread) { Debug.Assert((thread.State == KThreadState.Waiting) || (thread.State == KThreadState.WaitSuspended)); _oldThread = this.ActiveThread; this.ActiveThread = thread; } _oldThreadState = thread.State; thread.State = KThreadState.Ready; KCallback callback = thread.NotifiedCallbacks.Dequeue(); Log.WriteLine(Verbosity.Verbose, Feature.Bios, "Kernel::CheckCallbacks: issuing callback {0} on thread {1} (thread was {2})", callback.UID.ToString("X"), this.ActiveThread.UID.ToString("X"), _oldThread.UID.ToString("X")); _runningCallback = callback; // Format is arg1, arg2, commonAddress // arg1 = passed during notify // arg2 is passed during notify and given to use in argument Cpu.MarshalCall(this.ActiveThread.ContextID, callback.Address, new uint[] { callback.NotifyCount, callback.NotifyArguments, callback.CommonAddress }, new MarshalCompleteDelegate(this.CallbackComplete), 0); return(true); }
public void Exit(int code) { State = KThreadState.Dead; this.RemoveFromSchedule(); ExitCode = code; while (ExitWaiters.Count > 0) { KThread thread = ExitWaiters.Dequeue(); thread.Wake(0); } }
public void Start( uint argumentsLength, uint argumentsPointer ) { uint[] registers = new uint[ 32 ]; registers[ 4 ] = argumentsLength; registers[ 5 ] = argumentsPointer; registers[ 6 ] = 0; if( TlsBlock != null ) registers[ 26 ] = TlsBlock.Address; // TLS else registers[ 26 ] = 0; registers[ 28 ] = GlobalPointer; // gp - set by cpu? registers[ 29 ] = StackBlock.UpperBound; ContextID = Kernel.Cpu.AllocateContextStorage( EntryAddress, registers ); State = KThreadState.Ready; if( Diag.IsAttached == true ) { Breakpoint bp = new Breakpoint( Diag.Instance.Client.AllocateID(), BreakpointType.Stepping, this.EntryAddress ); Diag.Instance.CpuHook.AddBreakpoint( bp ); } Kernel.Threads.Add( this ); this.AddToSchedule(); }
public void Exit( int code ) { State = KThreadState.Dead; this.RemoveFromSchedule(); ExitCode = code; while( ExitWaiters.Count > 0 ) { KThread thread = ExitWaiters.Dequeue(); thread.Wake( 0 ); } }
public KThread( Kernel kernel, KModule module, KPartition partition, string name, uint entryAddress, int priority, KThreadAttributes attributes, uint stackSize ) { Debug.Assert( partition != null ); Kernel = kernel; Name = name; EntryAddress = entryAddress; InitialPriority = priority; Priority = priority; Attributes = attributes; Module = module; State = KThreadState.Stopped; ExitWaiters = new FastLinkedList<KThread>(); NotifiedCallbacks = new FastLinkedList<KCallback>(); //if( stackSize < 65535 ) //{ // Log.WriteLine( Verbosity.Normal, Feature.Bios, "KThread: attempt to allocate thread with a stack of {0} - forcing up to the minimum of 64K", stackSize ); // stackSize = 65535; //} RunClocks = 0; InterruptPreemptionCount = 0; ThreadPreemptionCount = 0; Partition = partition; StackBlock = partition.Allocate( string.Format( "Thread '{0}' Stack", name ), KAllocType.High, 0, stackSize ); Debug.Assert( StackBlock != null ); TlsBlock = partition.Allocate( string.Format( "Thread '{0}' TLS", name ), KAllocType.High, 0, 0x4000 ); // 16k of thread local storage --- enough? Debug.Assert( TlsBlock != null ); }