Beispiel #1
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);
        }
Beispiel #2
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 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;
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        public void Exit(int code)
        {
            State = KThreadState.Dead;
            this.RemoveFromSchedule();

            ExitCode = code;

            while (ExitWaiters.Count > 0)
            {
                KThread thread = ExitWaiters.Dequeue();
                thread.Wake(0);
            }
        }
Beispiel #6
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();
        }
Beispiel #7
0
        public void Exit( int code )
        {
            State = KThreadState.Dead;
            this.RemoveFromSchedule();

            ExitCode = code;

            while( ExitWaiters.Count > 0 )
            {
                KThread thread = ExitWaiters.Dequeue();
                thread.Wake( 0 );
            }
        }
Beispiel #8
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 );
        }