public void Enqueue(ServiceRequest req)
        {
            // For now disable interrupts:
            bool iflag = Processor.DisableInterrupts();

            spinLock.Acquire();
            try {
                if (head == null)
                {
                    head = req;
                    tail = req;
                }
                else
                {
                    tail.next = req;
                    tail      = req;
                }
            }
            finally {
                spinLock.Release();
            }

            // Signal an event : for now it is possible that it can be spirous one...
            enqueueEvent.InterruptAwareSet();

            // Reenable interrupts
            Processor.RestoreInterrupts(iflag);
        }
        // Block while the queue is empty, then return the head of the queue.
        public ServiceRequest Dequeue()
        {
            while (true)
            {
                // For now disable interrupts:
                bool iflag = Processor.DisableInterrupts();

                spinLock.Acquire();
                try {
                    if (tail != null)
                    {
                        ServiceRequest req = head;
                        if (req != tail)
                        {
                            head = req.next;
                        }
                        else
                        {
                            head = null;
                            tail = null;
                        }
                        return(req);
                    }
                }
                finally {
                    spinLock.Release();

                    // Reenable interrupts
                    Processor.RestoreInterrupts(iflag);
                }

                // Wait on event
                enqueueEvent.InterruptAwareWaitOne();
            }
        }
Esempio n. 3
0
        static internal unsafe void GCSynchronizationInterrupt()
        {
            // - member barriers and other issues with spinwaiting on a variable

            bool en = Processor.DisableInterrupts();

            //DebugStub.WriteLine("Processor {0} received GCSynchronizationInterrupt!\n",
            //__arglist(Processor.GetCurrentProcessorId()));


            ProcessorContext *current = Processor.GetCurrentProcessorContext();

            // Write value for this processor stating we ackknowledge the interrupt
            current->gcIpiGate = 1;

            // Question: Are we at a GC safe point? For all GC's?

            //
            // Spinwait until the GC processor indicates its done by clearing
            // this flag.
            //

            while (current->gcIpiGate != 0)
            {
                //
            }

            Processor.RestoreInterrupts(en);

            //DebugStub.WriteLine("Processor {0} done with GCSynchronizationInterrupt!\n",
            //__arglist(Processor.GetCurrentProcessorId()));

            return;
        }
Esempio n. 4
0
        public static void AddBytesSent(long bytes)
        {
            bool iflag = Processor.DisableInterrupts();

            bytesSent += bytes;
            Processor.RestoreInterrupts(iflag);
        }
Esempio n. 5
0
        public void SetNextTimerInterrupt(TimeSpan delta)
        {
            // Make sure that interrupts are disabled
            bool iflag = Processor.DisableInterrupts();

            TimeSpan start = delta;

            if (delta < timer.MinInterruptInterval)
            {
                delta = timer.MinInterruptInterval;
            }
            if (delta > timer.MaxInterruptInterval)
            {
                delta = timer.MaxInterruptInterval;
            }
#if false
            DebugStub.WriteLine("-- SetNextTimerInterrupt(delta={0}, start={1} [min={2},max={3})",
                                __arglist(delta.Ticks,
                                          start.Ticks,
                                          timer.MinInterruptInterval.Ticks,
                                          timer.MaxInterruptInterval.Ticks));
#endif
            timer.SetNextInterrupt(delta);

            // Restore interrupts if necessary
            Processor.RestoreInterrupts(iflag);
        }
Esempio n. 6
0
        private static void ApServiceLoop()
        {
            DebugStub.WriteLine("ApServiceThread is initialized and sleeping ...");
            MpExecution.MpCall mpCall;
            bool iflag;

            while (true)
            {
                abiEvent.WaitOne();

                DebugStub.WriteLine
                    ("HSG: ** cpu.{0} receives AbiCall interrupt",
                    __arglist(Processor.GetCurrentProcessorId()));

                // Current design: the boot processor will get all
                // unserved abi call. So we don't need to worry
                // missing any calls
                while (true)
                {
                    iflag  = Processor.DisableInterrupts();
                    mpCall = MpExecution.GetMpCall(Processor.GetCurrentProcessorId());
                    Processor.RestoreInterrupts(iflag);


                    // There is no unserved abi call, just break
                    if (mpCall == null)
                    {
                        break;
                    }

                    BspAbiStub.ProcessMpCall(Processor.GetCurrentProcessorId(), mpCall);
                }
            }
        }
Esempio n. 7
0
        internal static int MpMain(int cpu)
        {
            Tracing.Log(Tracing.Audit, "processor");
            Processor processor = Processor.EnableProcessor(cpu);

            // Initialize dispatcher
            Processor.InitializeDispatcher(cpu);

            // Initialize the HAL processor services
            // Note that this must occur after EnableProcessor, as the kernel
            // thread does not get bound until then. (It gets bound much
            // earlier in the boot processor case -- need to decide if this difference is
            // really appropriate.)
            Platform.Cpu(cpu).InitializeServices();

            Platform.InitializeHal(processor);

            Thread.CurrentThread.Affinity = cpu;

            Processor.ActivateTimer(cpu);

#if DEBUG_SYSTEM_LOCKUP
            // Spin one CPU on debugger. For instance with a quad-proc
            // box, spin CPU 3.
            while (cpu == 3)
            {
                if (DebugStub.PollForBreak() == true)
                {
                    DebugStub.Break();
                }
            }
#endif // DEBUG_SYSTEM_LOCKUP

            Processor.RestoreInterrupts(true);

            Tracing.Log(Tracing.Audit,
                        "Looping in processor's kernel thread.");
            //while (cpu > 0) {
            //    Thread.Yield();
            //}

            // This probably won't be the
            // ultimate way of dissociating kernel entry threads
            // from the kernel.
            DebugStub.Print("AP Processor started, about to wait\n");
            mpEndEvent.WaitOne();

            return(0);
        }
Esempio n. 8
0
        public static void RestoreInterrupts(bool enabled)
        {
            if ((ProcessPrivileges.GetCurrentPrivileges().AllowedOperations &
                 ProcessPrivileges.Operations.DisableInterrupts) != 0)
            {
                Processor.RestoreInterrupts(enabled);
            }
            else
            {
                //  ISSUE: Assert here until all instances get cleaned up from SIPs
                //  This assertion should be removed / replaced with something that would
                //  flag / halt / break only the bogus SIP, not the entire system

                VTable.Assert(false, "RestoreInterrupts called from unprivileged SIP");
            }
        }
Esempio n. 9
0
        public static void WaypointDump()
        {
            bool iflag = Processor.DisableInterrupts();

            DebugStub.WriteLine("Interrupts: {0}",
                                __arglist(Processor.CurrentProcessor.NumInterrupts
                                          - WaypointInterrupt));
            DebugStub.WriteLine("WPT Waypoint   Sequence   THD Diff");

            for (int i = 1; i < WaypointNumber; i++)
            {
                DebugStub.WriteLine("{0,3:d} {1,10:d} {2,10:d} {3,3:d} {4,10:d}",
                                    __arglist(
                                        i,
                                        Waypoints[i],
                                        WaypointSeq[i],
                                        WaypointThd[i].GetHashCode(),
                                        Waypoints[i] - Kernel.Waypoints[i - 1]));
            }
            Processor.RestoreInterrupts(iflag);
        }
Esempio n. 10
0
        private static void InitServices()
        {
            InitGCSupport();
            args = GetCommandLine();
            VTable.ParseArgs(args);

            ARM_PROGRESS("Kernel!011");
            InitSchedulerTypes();

            ARM_PROGRESS("Kernel!018");
            Controller.InitializeSystem();
            Tracing.InitializeSystem();

            ARM_PROGRESS("Kernel!019");
            //  Read the profiler settings. The values are assumed in kbytes
            //  convert them to bytes for direct consumption
            ProfilerBufferSize  = (uint)GetIntegerArgument("profiler", 0);
            ProfilerBufferSize *= 1024;

            ARM_PROGRESS("Kernel!020");

            SpinLock.StaticInitialize();

            int cpusLength;
            int cpuCount = GetCpuCount(out cpusLength);

            Processor.InitializeProcessorTable(cpusLength);
            ARM_PROGRESS("Kernel!021");
            Tracing.Log(Tracing.Audit, "processor");
            Processor processor = Processor.EnableProcessor(0);

            PEImage.Initialize();
            ARM_PROGRESS("Kernel!034");

            //  Initialize the sample profiling for the processor
            //  after the initial breakpoint in kd in the call
            //  PEImage.Initialize(). This will allow enabling profiling
            //  from kd, by overwriting the ProfilerBufferSize value
            processor.EnableProfiling();
            ARM_PROGRESS("Kernel!035");
            FlatPages.InitializeMemoryMonitoring();

            // initialize endpoints
            InitType(typeof(Microsoft.Singularity.Channels.EndpointCore));

            // TODO Bug 59: Currently broken, need to review paging build.
//#if PAGING
//            Microsoft.Singularity.Channels.EndpointTrusted.StaticInitialize();
//#endif
            ARM_PROGRESS("Kernel!036");

            // get the system manifest
            IoMemory systemManifest = GetSystemManifest();

            ARM_PROGRESS("Kernel!037");
            XmlReader xmlReader    = new XmlReader(systemManifest);
            XmlNode   xmlData      = xmlReader.Parse();
            XmlNode   manifestRoot = xmlData.GetChild("system");
            XmlNode   initConfig   = manifestRoot.GetChild("initConfig");

            ARM_PROGRESS("Kernel!038");

            PerfCounters.Initialize();
            // need to have processed the manifest before we can call Process initialize
            ARM_PROGRESS("Kernel!039");
            PrincipalImpl.Initialize(initConfig);

            ARM_PROGRESS("Kernel!040");
            Process.Initialize(manifestRoot.GetChild("processConfig"));

            InitIO(processor, initConfig, manifestRoot.GetChild("drivers"));

            InitBootTime();

            ARM_PROGRESS("Kernel!045");
            // From here on, we want lazy type initialization to worry about
            // competing threads.
            VTable.InitializeForMultipleThread();

            ARM_PROGRESS("Kernel!046");
            Console.WriteLine("Running C# Kernel of {0}", GetLinkDate());
            Console.WriteLine();

            // TODO: remove this
            Console.WriteLine("Current time: {0}", SystemClock.GetUtcTime().ToString("r"));
            ARM_PROGRESS("Kernel!047");

            InitScheduling();

            DirectoryService.StartNotificationThread();

            Console.WriteLine("Initializing Shared Heap Walker");
            ProtectionDomain.InitializeSharedHeapWalker();
            ARM_PROGRESS("Kernel!050");

            Console.WriteLine("Initializing Service Thread");
            ServiceThread.Initialize();
            ARM_PROGRESS("Kernel!051");

            GC.EnableHeap();
            GCProfilerLogger.StartProfiling();
            ARM_PROGRESS("Kernel!052");

            Tracing.Log(Tracing.Audit, "Waypoints init");
            Waypoints   = new long[2048];
            WaypointSeq = new int[2048];
            WaypointThd = new int[2048];

            Tracing.Log(Tracing.Audit, "Interrupts ON.");
            Processor.RestoreInterrupts(true);
            ARM_PROGRESS("Kernel!053");

#if ISA_ARM && TEST_GC
            for (int i = 0; i < 1000; i++)
            {
                DebugStub.WriteLine("Iteration {0}", __arglist(i));
                ArrayList a = new ArrayList();
                for (int j = 0; j < 128; j++)
                {
                    int size = 1024 * 1024;
                    a.Add(new byte [size]);
                }
            }
#endif // ISA_ARM

            ARM_PROGRESS("Kernel!054");

            Tracing.Log(Tracing.Audit, "Binder");
            Binder.Initialize(manifestRoot.GetChild("namingConventions"));

#if ISA_ARM
            DebugStub.WriteLine("Exporting local namespace to BSP\n");
            DirectoryService.ExportArmNamespace();
            DebugStub.WriteLine("Export complete...redirecting binder\n");
            Binder.RedirectRootRef();
            DebugStub.WriteLine("Binder redirect complete\n");
#endif

#if false
            Tracing.Log(Tracing.Audit, "Starting Security Service channels");
            PrincipalImpl.Export();
            ARM_PROGRESS("Kernel!055");
#endif
            Tracing.Log(Tracing.Audit, "Creating Root Directory.");

            //This can be moved below
            IoSystem.InitializeDirectoryService();
            ARM_PROGRESS("Kernel!055");

#if false
            // Start User space namespace manager
            Console.WriteLine("Starting Directory Service SIP");
            DirectoryService.StartUserSpaceDirectoryService();
#endif
            ARM_PROGRESS("Kernel!055.5");

#if !ISA_ARM
            Tracing.Log(Tracing.Audit, "Starting Security Service channels");
            PrincipalImpl.Export();
#endif

            ARM_PROGRESS("Kernel!056");

            Console.WriteLine("Initializing system channels");

            // starting channels services
            DebugStub.Print("Initializing Channel Services\n");
            ChannelDeliveryImplService.Initialize();

            ARM_PROGRESS("Kernel!057");
            ConsoleOutput.Initialize();

            ARM_PROGRESS("Kernel!058");

            // Initialize MP after Binder and ConsoleOutput
            // are initialized so there are no
            // initialization races if the additional
            // threads try to use them.
            Tracing.Log(Tracing.Audit, "Starting additional processors");

            // For ABI to ARM support
            MpExecution.Initialize();
            ARM_PROGRESS("Kernel!059");

            mpEndEvent = new ManualResetEvent(false);

            Tracing.Log(Tracing.Audit, "Initializing Volume Manager.");

#if !ISA_ARM
            IoSystem.InitializeVolumeManager();
#endif // ISA_ARM
            ARM_PROGRESS("Kernel!060");

            InitDrivers();

            if (cpuCount > 1)
            {
                unsafe {
                    Console.WriteLine("Enabling {0} cpus out of {1} real cpus\n", cpuCount, Platform.ThePlatform.CpuRealCount);
                }
                Processor.EnableMoreProcessors(cpuCount);
                ARM_PROGRESS("Kernel!064");
            }

            Tracing.Log(Tracing.Audit, "Initializing Service Manager.");
            IoSystem.InitializeServiceManager(manifestRoot.GetChild("serviceConfig"));
            ARM_PROGRESS("Kernel!065");

            InitDiagnostics();

#if !ISA_ARM
            // At this point consider kernel finshed booting
            hasBooted = true;
#endif // ISA_ARM

            Processor.StartSampling();
            ARM_PROGRESS("Kernel!069");

            Microsoft.Singularity.KernelDebugger.KdFilesNamespace.StartNamespaceThread();
            ARM_PROGRESS("Kernel!070");
        }