singrdk/base/Kernel/Singularity/V1/Services/ProcessService.cs

405 lines
14 KiB
C#

////////////////////////////////////////////////////////////////////////////////
//
// Microsoft Research Singularity - Singularity ABI
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// File: ProcessService.cs
//
// Note:
//
using System;
using System.Runtime.CompilerServices;
using System.Threading;
using Microsoft.Singularity;
using Microsoft.Singularity.Memory;
using Microsoft.Singularity.Security;
using Microsoft.Singularity.Io;
using Microsoft.Singularity.V1.Security;
using Microsoft.Singularity.Eventing;
namespace Microsoft.Singularity.V1.Services
{
[CLSCompliant(false)]
public struct LogEntry
{
}
public enum ParameterCode {
Success,
OutOfRange,
NotSet,
Retrieved,
Undefined,
}
[CLSCompliant(false)]
[AccessedByRuntime("referenced from Tracing.cpp")]
public struct ProcessService
{
// In order to pass the arguments to the kernel, we first need to
// flatten the arguments parameter from an array of strings to
// an array of characters (containing the contents of the strings).
// If argVector is null we compute the the length needed to store
// the result. It is up to the calling process to then allocate
// the memory and call again.
private static unsafe int FlattenStringArray(string[] arguments,
int* argLengths,
char* argVector
)
{
int totalCharacters = 0;
int len = arguments.Length;
for (int arg = 0; arg < len; arg++) {
string argstring = arguments[arg];
if (argstring == null) continue;
totalCharacters += argstring.Length;
}
if (argVector == null) {
return totalCharacters;
}
int offset = 0;
for (int arg = 0; arg < len; arg++) {
string argstring = arguments[arg];
if (argstring == null) {
argLengths[arg] = 0;
continue;
}
int alen = argstring.Length;
//argstring.CopyTo(0, argVector, offset, alen);
for (int i = 0; i < alen; i++) {
argVector[offset+i] = argstring[i];
}
offset += alen;
argLengths[arg] = alen;
}
return totalCharacters;
}
[ExternalEntryPoint]
public static void Stop(int exitCode)
{
Tracing.Log(Tracing.Debug, "ProcessService.Stop(exit={0})",
(UIntPtr)unchecked((uint)exitCode));
Thread.CurrentProcess.Stop(exitCode);
}
[ExternalEntryPoint]
public static int GetCpuCount()
{
return Processor.GetRunningProcessorCount();
}
[ExternalEntryPoint]
public static TimeSpan GetUpTime()
{
TimeSpan ts = SystemClock.KernelUpTime;
return ts;
}
[ExternalEntryPoint]
public static DateTime GetUtcTime()
{
DateTime dt = SystemClock.GetUtcTime();
return dt;
}
[ExternalEntryPoint]
public static long GetCycleCount()
{
return (long)Processor.CycleCount;
}
[ExternalEntryPoint]
public static long GetCyclesPerSecond()
{
Kernel.Waypoint(300);
return (long)Processor.CyclesPerSecond;
}
[ExternalEntryPoint]
public static long GetContextSwitchCount()
{
int processors = Processor.CpuCount;
long contextSwitches = 0;
for (int processor = 0; processor < processors; processor++) {
Processor p = Processor.GetProcessor(processor);
contextSwitches += p.NumContextSwitches;
}
return contextSwitches;
}
[ExternalEntryPoint]
public static void SetGcPerformanceCounters(TimeSpan spent, long bytes)
{
Thread.CurrentProcess.SetGcPerformanceCounters(spent, bytes);
}
[ExternalEntryPoint]
public static long GetKernelGcCount()
{
int collectorCount;
long collectorMillis;
long collectorBytes;
GC.PerformanceCounters(out collectorCount,
out collectorMillis,
out collectorBytes);
return collectorCount;
}
[ExternalEntryPoint]
public static long GetKernelBootCount()
{
return Resources.GetWarmBootCount();
}
[ExternalEntryPoint]
public static long GetKernelInterruptCount()
{
int processors = Processor.CpuCount;
long interrupts = 0;
for (int processor = 0; processor < processors; processor++) {
Processor p = Processor.GetProcessor(processor);
interrupts += p.NumInterrupts;
}
return interrupts;
}
[ExternalEntryPoint]
public static ushort GetCurrentProcessId()
{
return (ushort)Thread.CurrentProcess.ProcessId;
}
//
//[ExternalEntryPoint]
//public static PrincipalHandle GetCurrentPrincipal()
//{
// return new PrincipalHandle(Thread.CurrentProcess.PrincipalId.val);
//}
//
[ExternalEntryPoint]
// Return parameter is really: DirectoryService.Imp opt(ExHeap) *
public static unsafe SharedHeapService.Allocation * GetNamespaceEndpoint()
{
return (SharedHeapService.Allocation *)
Thread.CurrentProcess.GetNamespaceEndpoint();
}
[ExternalEntryPoint]
public static int GetStartupEndpointCount() {
return Thread.CurrentProcess.GetStartupEndpointCount();
}
[ExternalEntryPoint]
// Return parameter is really: ExtensionContract.Exp opt(ExHeap) *
public static unsafe SharedHeapService.Allocation * GetStartupEndpoint(int arg)
{
return (SharedHeapService.Allocation *)
Thread.CurrentProcess.GetStartupEndpoint(arg);
}
[ExternalEntryPoint]
// Parameter is really: ExtensionContract.Exp opt(ExHeap) *
public static unsafe void SetStartupEndpoint(int arg,
SharedHeapService.Allocation * ep)
{
SharedHeap.Allocation * mep = (SharedHeap.Allocation *)ep;
Thread.CurrentProcess.SetEndpoint(arg, ref mep);
}
[ExternalEntryPoint]
public static int GetStartupArgCount()
{
return Thread.CurrentProcess.GetStartupArgCount();
}
[ExternalEntryPoint]
public static unsafe int GetStartupArg(int arg, char * output, int maxput)
{
string s = Thread.CurrentProcess.GetStartupArg(arg);
Tracing.Log(Tracing.Debug,
"Process.GetStartupArg(arg={0}, out={1:x8}, max={2}) = {3}",
(UIntPtr)unchecked((uint)arg),
(UIntPtr)output,
(UIntPtr)unchecked((uint)maxput),
(UIntPtr)unchecked((uint)(s != null ? s.Length : 0)));
if (s == null) {
return 0;
}
if (output == null) {
return s.Length + 1;
}
return s.InternalGetChars(output, maxput);
}
[ExternalEntryPoint]
public static TimeSpan GetThreadTime() {
return Thread.CurrentThread.ExecutionTime;
}
[ExternalEntryPoint]
public static long GetThreadsCreatedCount() {
return PerfCounters.ThreadsCreated;
}
[ExternalEntryPoint]
public static unsafe bool GetSharedSourceHandlesImpl(uint infoId,
UIntPtr * storageHandle,
UIntPtr * sourceHandle,
UIntPtr * eventTypeHandle)
{
return GetSharedSourceHandles(infoId, out *storageHandle, out *sourceHandle, out *eventTypeHandle);
}
[AccessedByRuntime("referenced from Monitoring.cpp")]
public static unsafe bool GetSharedSourceHandles(uint infoId,
out UIntPtr storageHandle,
out UIntPtr sourceHandle,
out UIntPtr eventTypeHandle)
{
return Controller.GetSharedSourceHandles(infoId, out storageHandle, out sourceHandle, out eventTypeHandle);
}
[ExternalEntryPoint]
public static void Waypoint0()
{
Kernel.Waypoint0();
}
[ExternalEntryPoint]
public static void Waypoint(int num)
{
Kernel.Waypoint(num);
}
[ExternalEntryPoint]
public static void WaypointDone()
{
Kernel.WaypointDone();
}
[ExternalEntryPoint]
public static void WaypointDump()
{
Kernel.WaypointDump();
}
[ExternalEntryPoint]
public static int GetStartupBoolArgCount() {
return Thread.CurrentProcess.GetStartupBoolArgCount();
}
[ExternalEntryPoint]
public static int GetStartupLongArgCount() {
return Thread.CurrentProcess.GetStartupLongArgCount();
}
[ExternalEntryPoint]
public static int GetStartupStringArgCount() {
return Thread.CurrentProcess.GetStartupStringArgCount();
}
[ExternalEntryPoint]
public static int GetStartupStringArrayArgCount() {
return Thread.CurrentProcess.GetStartupStringArrayArgCount();
}
[ExternalEntryPoint]
public static unsafe ParameterCode GetStartupLongArgImpl(
int index,
long * value)
{
return GetStartupLongArg(index, out *value);
}
public static ParameterCode GetStartupLongArg(int index, out long value) {
return (ParameterCode) Thread.CurrentProcess.GetStartupLongArg(index, out value);
}
[ExternalEntryPoint]
public static unsafe ParameterCode GetStartupBoolArgImpl(
int index,
bool * value)
{
return GetStartupBoolArg(index, out *value);
}
public static ParameterCode GetStartupBoolArg(int index, out bool value) {
return (ParameterCode)Thread.CurrentProcess.GetStartupBoolArg(index, out value);
}
[ExternalEntryPoint]
public static unsafe ParameterCode GetStartupStringArrayArgImpl(
int index,
char *strbuff,
int *len,
int *arrayLength,
int *totalCharCount)
{
ParameterCode code;
string[] strings;
code = (ParameterCode) Thread.CurrentProcess.GetStartupStringArrayArg(index, out strings);
if (code != ParameterCode.Success) {
*arrayLength = 0;
*totalCharCount = 0;
return code;
}
if (strings == null) {
*arrayLength = 0;
*totalCharCount = 0;
return ParameterCode.NotSet;
}
*totalCharCount = FlattenStringArray(strings, len, strbuff);
*arrayLength = strings.Length;
return ParameterCode.Success;
}
[ExternalEntryPoint]
public static unsafe ParameterCode GetStartupStringArgImpl(
int arg,
char * output,
int * maxput)
{
return GetStartupStringArg(arg, output, ref *maxput);
}
public static unsafe ParameterCode GetStartupStringArg(int arg, char * output, ref int maxput)
{
string s;
ParameterCode code = (ParameterCode)Thread.CurrentProcess.GetStartupStringArg(arg, out s);
Tracing.Log(Tracing.Debug,
"Process.GetStartupStringArg(arg={0}, out={1:x8}, max={2}) = {3}",
(UIntPtr)unchecked((uint)arg),
(UIntPtr)output,
(UIntPtr)unchecked((uint)maxput),
(UIntPtr)unchecked((uint)(s != null ? s.Length : 0)));
if (code != ParameterCode.Success) {
return code;
}
if (output == null) {
if (s == null) maxput = 0;
else maxput = s.Length ;
return ParameterCode.Success;
}
if (s != null) s.InternalGetChars(output, maxput);
return ParameterCode.Success;
}
}
}