Adjust naming conventions and general refactoring in HLE Project (#490)

* Rename enum fields

* Naming conventions

* Remove unneeded ".this"

* Remove unneeded semicolons

* Remove unused Usings

* Don't use var

* Remove unneeded enum underlying types

* Explicitly label class visibility

* Remove unneeded @ prefixes

* Remove unneeded commas

* Remove unneeded if expressions

* Method doesn't use unsafe code

* Remove unneeded casts

* Initialized objects don't need an empty constructor

* Remove settings from DotSettings

* Revert "Explicitly label class visibility"

This reverts commit ad5eb5787c.

* Small changes

* Revert external enum renaming

* Changes from feedback

* Remove unneeded property setters
This commit is contained in:
Alex Barney 2018-12-04 14:23:37 -06:00 committed by gdkchan
parent c86aacde76
commit 85dbb9559a
299 changed files with 12268 additions and 12276 deletions

View file

@ -4,22 +4,22 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class ArraySubscriptingExpression : BaseNode
{
private BaseNode LeftNode;
private BaseNode Subscript;
private BaseNode _leftNode;
private BaseNode _subscript;
public ArraySubscriptingExpression(BaseNode LeftNode, BaseNode Subscript) : base(NodeType.ArraySubscriptingExpression)
public ArraySubscriptingExpression(BaseNode leftNode, BaseNode subscript) : base(NodeType.ArraySubscriptingExpression)
{
this.LeftNode = LeftNode;
this.Subscript = Subscript;
_leftNode = leftNode;
_subscript = subscript;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Writer.Write("(");
LeftNode.Print(Writer);
Writer.Write(")[");
Subscript.Print(Writer);
Writer.Write("]");
writer.Write("(");
_leftNode.Print(writer);
writer.Write(")[");
_subscript.Print(writer);
writer.Write("]");
}
}
}

View file

@ -4,20 +4,20 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class ArrayType : BaseNode
{
private BaseNode Base;
private BaseNode DimensionExpression;
private string DimensionString;
private BaseNode _base;
private BaseNode _dimensionExpression;
private string _dimensionString;
public ArrayType(BaseNode Base, BaseNode DimensionExpression = null) : base(NodeType.ArrayType)
public ArrayType(BaseNode Base, BaseNode dimensionExpression = null) : base(NodeType.ArrayType)
{
this.Base = Base;
this.DimensionExpression = DimensionExpression;
_base = Base;
_dimensionExpression = dimensionExpression;
}
public ArrayType(BaseNode Base, string DimensionString) : base(NodeType.ArrayType)
public ArrayType(BaseNode Base, string dimensionString) : base(NodeType.ArrayType)
{
this.Base = Base;
this.DimensionString = DimensionString;
_base = Base;
_dimensionString = dimensionString;
}
public override bool HasRightPart()
@ -30,30 +30,30 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
return true;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Base.PrintLeft(Writer);
_base.PrintLeft(writer);
}
public override void PrintRight(TextWriter Writer)
public override void PrintRight(TextWriter writer)
{
// FIXME: detect if previous char was a ].
Writer.Write(" ");
writer.Write(" ");
Writer.Write("[");
writer.Write("[");
if (DimensionString != null)
if (_dimensionString != null)
{
Writer.Write(DimensionString);
writer.Write(_dimensionString);
}
else if (DimensionExpression != null)
else if (_dimensionExpression != null)
{
DimensionExpression.Print(Writer);
_dimensionExpression.Print(writer);
}
Writer.Write("]");
writer.Write("]");
Base.PrintRight(Writer);
_base.PrintRight(writer);
}
}
}

View file

@ -4,7 +4,7 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public enum NodeType
{
CVQualifierType,
CvQualifierType,
SimpleReferenceType,
NameType,
EncodedFunction,
@ -62,22 +62,22 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public NodeType Type { get; protected set; }
public BaseNode(NodeType Type)
public BaseNode(NodeType type)
{
this.Type = Type;
Type = type;
}
public virtual void Print(TextWriter Writer)
public virtual void Print(TextWriter writer)
{
PrintLeft(Writer);
PrintLeft(writer);
if (HasRightPart())
{
PrintRight(Writer);
PrintRight(writer);
}
}
public abstract void PrintLeft(TextWriter Writer);
public abstract void PrintLeft(TextWriter writer);
public virtual bool HasRightPart()
{
@ -99,15 +99,15 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
return null;
}
public virtual void PrintRight(TextWriter Writer) {}
public virtual void PrintRight(TextWriter writer) {}
public override string ToString()
{
StringWriter Writer = new StringWriter();
StringWriter writer = new StringWriter();
Print(Writer);
Print(writer);
return Writer.ToString();
return writer.ToString();
}
}
}

View file

@ -4,37 +4,37 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class BinaryExpression : BaseNode
{
private BaseNode LeftPart;
private string Name;
private BaseNode RightPart;
private BaseNode _leftPart;
private string _name;
private BaseNode _rightPart;
public BinaryExpression(BaseNode LeftPart, string Name, BaseNode RightPart) : base(NodeType.BinaryExpression)
public BinaryExpression(BaseNode leftPart, string name, BaseNode rightPart) : base(NodeType.BinaryExpression)
{
this.LeftPart = LeftPart;
this.Name = Name;
this.RightPart = RightPart;
_leftPart = leftPart;
_name = name;
_rightPart = rightPart;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
if (Name.Equals(">"))
if (_name.Equals(">"))
{
Writer.Write("(");
writer.Write("(");
}
Writer.Write("(");
LeftPart.Print(Writer);
Writer.Write(") ");
writer.Write("(");
_leftPart.Print(writer);
writer.Write(") ");
Writer.Write(Name);
writer.Write(_name);
Writer.Write(" (");
RightPart.Print(Writer);
Writer.Write(")");
writer.Write(" (");
_rightPart.Print(writer);
writer.Write(")");
if (Name.Equals(">"))
if (_name.Equals(">"))
{
Writer.Write(")");
writer.Write(")");
}
}
}

View file

@ -4,37 +4,37 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class BracedExpression : BaseNode
{
private BaseNode Element;
private BaseNode Expression;
private bool IsArrayExpression;
private BaseNode _element;
private BaseNode _expression;
private bool _isArrayExpression;
public BracedExpression(BaseNode Element, BaseNode Expression, bool IsArrayExpression) : base(NodeType.BracedExpression)
public BracedExpression(BaseNode element, BaseNode expression, bool isArrayExpression) : base(NodeType.BracedExpression)
{
this.Element = Element;
this.Expression = Expression;
this.IsArrayExpression = IsArrayExpression;
_element = element;
_expression = expression;
_isArrayExpression = isArrayExpression;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
if (IsArrayExpression)
if (_isArrayExpression)
{
Writer.Write("[");
Element.Print(Writer);
Writer.Write("]");
writer.Write("[");
_element.Print(writer);
writer.Write("]");
}
else
{
Writer.Write(".");
Element.Print(Writer);
writer.Write(".");
_element.Print(writer);
}
if (!Expression.GetType().Equals(NodeType.BracedExpression) || !Expression.GetType().Equals(NodeType.BracedRangeExpression))
if (!_expression.GetType().Equals(NodeType.BracedExpression) || !_expression.GetType().Equals(NodeType.BracedRangeExpression))
{
Writer.Write(" = ");
writer.Write(" = ");
}
Expression.Print(Writer);
_expression.Print(writer);
}
}
}

View file

@ -4,31 +4,31 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class BracedRangeExpression : BaseNode
{
private BaseNode FirstNode;
private BaseNode LastNode;
private BaseNode Expression;
private BaseNode _firstNode;
private BaseNode _lastNode;
private BaseNode _expression;
public BracedRangeExpression(BaseNode FirstNode, BaseNode LastNode, BaseNode Expression) : base(NodeType.BracedRangeExpression)
public BracedRangeExpression(BaseNode firstNode, BaseNode lastNode, BaseNode expression) : base(NodeType.BracedRangeExpression)
{
this.FirstNode = FirstNode;
this.LastNode = LastNode;
this.Expression = Expression;
_firstNode = firstNode;
_lastNode = lastNode;
_expression = expression;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Writer.Write("[");
FirstNode.Print(Writer);
Writer.Write(" ... ");
LastNode.Print(Writer);
Writer.Write("]");
writer.Write("[");
_firstNode.Print(writer);
writer.Write(" ... ");
_lastNode.Print(writer);
writer.Write("]");
if (!Expression.GetType().Equals(NodeType.BracedExpression) || !Expression.GetType().Equals(NodeType.BracedRangeExpression))
if (!_expression.GetType().Equals(NodeType.BracedExpression) || !_expression.GetType().Equals(NodeType.BracedRangeExpression))
{
Writer.Write(" = ");
writer.Write(" = ");
}
Expression.Print(Writer);
_expression.Print(writer);
}
}
}

View file

@ -5,20 +5,20 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class CallExpression : NodeArray
{
private BaseNode Callee;
private BaseNode _callee;
public CallExpression(BaseNode Callee, List<BaseNode> Nodes) : base(Nodes, NodeType.CallExpression)
public CallExpression(BaseNode callee, List<BaseNode> nodes) : base(nodes, NodeType.CallExpression)
{
this.Callee = Callee;
_callee = callee;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Callee.Print(Writer);
_callee.Print(writer);
Writer.Write("(");
Writer.Write(string.Join<BaseNode>(", ", Nodes.ToArray()));
Writer.Write(")");
writer.Write("(");
writer.Write(string.Join<BaseNode>(", ", Nodes.ToArray()));
writer.Write(")");
}
}
}

View file

@ -4,25 +4,25 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class CastExpression : BaseNode
{
private string Kind;
private BaseNode To;
private BaseNode From;
private string _kind;
private BaseNode _to;
private BaseNode _from;
public CastExpression(string Kind, BaseNode To, BaseNode From) : base(NodeType.CastExpression)
public CastExpression(string kind, BaseNode to, BaseNode from) : base(NodeType.CastExpression)
{
this.Kind = Kind;
this.To = To;
this.From = From;
_kind = kind;
_to = to;
_from = from;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Writer.Write(Kind);
Writer.Write("<");
To.PrintLeft(Writer);
Writer.Write(">(");
From.PrintLeft(Writer);
Writer.Write(")");
writer.Write(_kind);
writer.Write("<");
_to.PrintLeft(writer);
writer.Write(">(");
_from.PrintLeft(writer);
writer.Write(")");
}
}
}

View file

@ -4,26 +4,26 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class ConditionalExpression : BaseNode
{
private BaseNode ThenNode;
private BaseNode ElseNode;
private BaseNode ConditionNode;
private BaseNode _thenNode;
private BaseNode _elseNode;
private BaseNode _conditionNode;
public ConditionalExpression(BaseNode ConditionNode, BaseNode ThenNode, BaseNode ElseNode) : base(NodeType.ConditionalExpression)
public ConditionalExpression(BaseNode conditionNode, BaseNode thenNode, BaseNode elseNode) : base(NodeType.ConditionalExpression)
{
this.ThenNode = ThenNode;
this.ConditionNode = ConditionNode;
this.ElseNode = ElseNode;
_thenNode = thenNode;
_conditionNode = conditionNode;
_elseNode = elseNode;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Writer.Write("(");
ConditionNode.Print(Writer);
Writer.Write(") ? (");
ThenNode.Print(Writer);
Writer.Write(") : (");
ElseNode.Print(Writer);
Writer.Write(")");
writer.Write("(");
_conditionNode.Print(writer);
writer.Write(") ? (");
_thenNode.Print(writer);
writer.Write(") : (");
_elseNode.Print(writer);
writer.Write(")");
}
}
}

View file

@ -4,21 +4,21 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class ConversionExpression : BaseNode
{
private BaseNode TypeNode;
private BaseNode Expressions;
private BaseNode _typeNode;
private BaseNode _expressions;
public ConversionExpression(BaseNode TypeNode, BaseNode Expressions) : base(NodeType.ConversionExpression)
public ConversionExpression(BaseNode typeNode, BaseNode expressions) : base(NodeType.ConversionExpression)
{
this.TypeNode = TypeNode;
this.Expressions = Expressions;
_typeNode = typeNode;
_expressions = expressions;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Writer.Write("(");
TypeNode.Print(Writer);
Writer.Write(")(");
Expressions.Print(Writer);
writer.Write("(");
_typeNode.Print(writer);
writer.Write(")(");
_expressions.Print(writer);
}
}
}

View file

@ -4,12 +4,12 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class ConversionOperatorType : ParentNode
{
public ConversionOperatorType(BaseNode Child) : base(NodeType.ConversionOperatorType, Child) { }
public ConversionOperatorType(BaseNode child) : base(NodeType.ConversionOperatorType, child) { }
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Writer.Write("operator ");
Child.Print(Writer);
writer.Write("operator ");
Child.Print(writer);
}
}
}

View file

@ -4,21 +4,21 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class CtorDtorNameType : ParentNode
{
private bool IsDestructor;
private bool _isDestructor;
public CtorDtorNameType(BaseNode Name, bool IsDestructor) : base(NodeType.CtorDtorNameType, Name)
public CtorDtorNameType(BaseNode name, bool isDestructor) : base(NodeType.CtorDtorNameType, name)
{
this.IsDestructor = IsDestructor;
_isDestructor = isDestructor;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
if (IsDestructor)
if (_isDestructor)
{
Writer.Write("~");
writer.Write("~");
}
Writer.Write(Child.GetName());
writer.Write(Child.GetName());
}
}
}

View file

@ -4,21 +4,21 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class CtorVtableSpecialName : BaseNode
{
private BaseNode FirstType;
private BaseNode SecondType;
private BaseNode _firstType;
private BaseNode _secondType;
public CtorVtableSpecialName(BaseNode FirstType, BaseNode SecondType) : base(NodeType.CtorVtableSpecialName)
public CtorVtableSpecialName(BaseNode firstType, BaseNode secondType) : base(NodeType.CtorVtableSpecialName)
{
this.FirstType = FirstType;
this.SecondType = SecondType;
_firstType = firstType;
_secondType = secondType;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Writer.Write("construction vtable for ");
FirstType.Print(Writer);
Writer.Write("-in-");
SecondType.Print(Writer);
writer.Write("construction vtable for ");
_firstType.Print(writer);
writer.Write("-in-");
_secondType.Print(writer);
}
}
}

View file

@ -4,30 +4,30 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class DeleteExpression : ParentNode
{
private bool IsGlobal;
private bool IsArrayExpression;
private bool _isGlobal;
private bool _isArrayExpression;
public DeleteExpression(BaseNode Child, bool IsGlobal, bool IsArrayExpression) : base(NodeType.DeleteExpression, Child)
public DeleteExpression(BaseNode child, bool isGlobal, bool isArrayExpression) : base(NodeType.DeleteExpression, child)
{
this.IsGlobal = IsGlobal;
this.IsArrayExpression = IsArrayExpression;
_isGlobal = isGlobal;
_isArrayExpression = isArrayExpression;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
if (IsGlobal)
if (_isGlobal)
{
Writer.Write("::");
writer.Write("::");
}
Writer.Write("delete");
writer.Write("delete");
if (IsArrayExpression)
if (_isArrayExpression)
{
Writer.Write("[] ");
writer.Write("[] ");
}
Child.Print(Writer);
Child.Print(writer);
}
}
}

View file

@ -4,12 +4,12 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class DtorName : ParentNode
{
public DtorName(BaseNode Name) : base(NodeType.DtOrName, Name) { }
public DtorName(BaseNode name) : base(NodeType.DtOrName, name) { }
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Writer.Write("~");
Child.PrintLeft(Writer);
writer.Write("~");
Child.PrintLeft(writer);
}
}
}

View file

@ -4,13 +4,13 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class DynamicExceptionSpec : ParentNode
{
public DynamicExceptionSpec(BaseNode Child) : base(NodeType.DynamicExceptionSpec, Child) { }
public DynamicExceptionSpec(BaseNode child) : base(NodeType.DynamicExceptionSpec, child) { }
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Writer.Write("throw(");
Child.Print(Writer);
Writer.Write(")");
writer.Write("throw(");
Child.Print(writer);
writer.Write(")");
}
}
}

View file

@ -4,18 +4,18 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class ElaboratedType : ParentNode
{
private string Elaborated;
private string _elaborated;
public ElaboratedType(string Elaborated, BaseNode Type) : base(NodeType.ElaboratedType, Type)
public ElaboratedType(string elaborated, BaseNode type) : base(NodeType.ElaboratedType, type)
{
this.Elaborated = Elaborated;
_elaborated = elaborated;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Writer.Write(Elaborated);
Writer.Write(" ");
Child.Print(Writer);
writer.Write(_elaborated);
writer.Write(" ");
Child.Print(writer);
}
}
}

View file

@ -4,22 +4,22 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class EnclosedExpression : BaseNode
{
private string Prefix;
private BaseNode Expression;
private string Postfix;
private string _prefix;
private BaseNode _expression;
private string _postfix;
public EnclosedExpression(string Prefix, BaseNode Expression, string Postfix) : base(NodeType.EnclosedExpression)
public EnclosedExpression(string prefix, BaseNode expression, string postfix) : base(NodeType.EnclosedExpression)
{
this.Prefix = Prefix;
this.Expression = Expression;
this.Postfix = Postfix;
_prefix = prefix;
_expression = expression;
_postfix = postfix;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Writer.Write(Prefix);
Expression.Print(Writer);
Writer.Write(Postfix);
writer.Write(_prefix);
_expression.Print(writer);
writer.Write(_postfix);
}
}
}

View file

@ -4,36 +4,36 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class EncodedFunction : BaseNode
{
private BaseNode Name;
private BaseNode Params;
private BaseNode CV;
private BaseNode Ref;
private BaseNode Attrs;
private BaseNode Ret;
private BaseNode _name;
private BaseNode _params;
private BaseNode _cv;
private BaseNode _ref;
private BaseNode _attrs;
private BaseNode _ret;
public EncodedFunction(BaseNode Name, BaseNode Params, BaseNode CV, BaseNode Ref, BaseNode Attrs, BaseNode Ret) : base(NodeType.NameType)
public EncodedFunction(BaseNode name, BaseNode Params, BaseNode cv, BaseNode Ref, BaseNode attrs, BaseNode ret) : base(NodeType.NameType)
{
this.Name = Name;
this.Params = Params;
this.CV = CV;
this.Ref = Ref;
this.Attrs = Attrs;
this.Ret = Ret;
_name = name;
_params = Params;
_cv = cv;
_ref = Ref;
_attrs = attrs;
_ret = ret;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
if (Ret != null)
if (_ret != null)
{
Ret.PrintLeft(Writer);
_ret.PrintLeft(writer);
if (!Ret.HasRightPart())
if (!_ret.HasRightPart())
{
Writer.Write(" ");
writer.Write(" ");
}
}
Name.Print(Writer);
_name.Print(writer);
}
@ -42,35 +42,35 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
return true;
}
public override void PrintRight(TextWriter Writer)
public override void PrintRight(TextWriter writer)
{
Writer.Write("(");
writer.Write("(");
if (Params != null)
if (_params != null)
{
Params.Print(Writer);
_params.Print(writer);
}
Writer.Write(")");
writer.Write(")");
if (Ret != null)
if (_ret != null)
{
Ret.PrintRight(Writer);
_ret.PrintRight(writer);
}
if (CV != null)
if (_cv != null)
{
CV.Print(Writer);
_cv.Print(writer);
}
if (Ref != null)
if (_ref != null)
{
Ref.Print(Writer);
_ref.Print(writer);
}
if (Attrs != null)
if (_attrs != null)
{
Attrs.Print(Writer);
_attrs.Print(writer);
}
}
}

View file

@ -4,45 +4,45 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class FoldExpression : BaseNode
{
private bool IsLeftFold;
private string OperatorName;
private BaseNode Expression;
private BaseNode Initializer;
private bool _isLeftFold;
private string _operatorName;
private BaseNode _expression;
private BaseNode _initializer;
public FoldExpression(bool IsLeftFold, string OperatorName, BaseNode Expression, BaseNode Initializer) : base(NodeType.FunctionParameter)
public FoldExpression(bool isLeftFold, string operatorName, BaseNode expression, BaseNode initializer) : base(NodeType.FunctionParameter)
{
this.IsLeftFold = IsLeftFold;
this.OperatorName = OperatorName;
this.Expression = Expression;
this.Initializer = Initializer;
_isLeftFold = isLeftFold;
_operatorName = operatorName;
_expression = expression;
_initializer = initializer;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Writer.Write("(");
writer.Write("(");
if (IsLeftFold && Initializer != null)
if (_isLeftFold && _initializer != null)
{
Initializer.Print(Writer);
Writer.Write(" ");
Writer.Write(OperatorName);
Writer.Write(" ");
_initializer.Print(writer);
writer.Write(" ");
writer.Write(_operatorName);
writer.Write(" ");
}
Writer.Write(IsLeftFold ? "... " : " ");
Writer.Write(OperatorName);
Writer.Write(!IsLeftFold ? " ..." : " ");
Expression.Print(Writer);
writer.Write(_isLeftFold ? "... " : " ");
writer.Write(_operatorName);
writer.Write(!_isLeftFold ? " ..." : " ");
_expression.Print(writer);
if (!IsLeftFold && Initializer != null)
if (!_isLeftFold && _initializer != null)
{
Initializer.Print(Writer);
Writer.Write(" ");
Writer.Write(OperatorName);
Writer.Write(" ");
_initializer.Print(writer);
writer.Write(" ");
writer.Write(_operatorName);
writer.Write(" ");
}
Writer.Write(")");
writer.Write(")");
}
}
}

View file

@ -6,11 +6,11 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
// TODO: Compute inside the Demangler
public BaseNode Reference;
private int Index;
private int _index;
public ForwardTemplateReference(int Index) : base(NodeType.ForwardTemplateReference)
public ForwardTemplateReference(int index) : base(NodeType.ForwardTemplateReference)
{
this.Index = Index;
_index = index;
}
public override string GetName()
@ -18,14 +18,14 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
return Reference.GetName();
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Reference.PrintLeft(Writer);
Reference.PrintLeft(writer);
}
public override void PrintRight(TextWriter Writer)
public override void PrintRight(TextWriter writer)
{
Reference.PrintRight(Writer);
Reference.PrintRight(writer);
}
public override bool HasRightPart()

View file

@ -4,20 +4,20 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class FunctionParameter : BaseNode
{
private string Number;
private string _number;
public FunctionParameter(string Number) : base(NodeType.FunctionParameter)
public FunctionParameter(string number) : base(NodeType.FunctionParameter)
{
this.Number = Number;
_number = number;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Writer.Write("fp ");
writer.Write("fp ");
if (Number != null)
if (_number != null)
{
Writer.Write(Number);
writer.Write(_number);
}
}
}

View file

@ -4,47 +4,47 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class FunctionType : BaseNode
{
private BaseNode ReturnType;
private BaseNode Params;
private BaseNode CVQualifier;
private SimpleReferenceType ReferenceQualifier;
private BaseNode ExceptionSpec;
private BaseNode _returnType;
private BaseNode _params;
private BaseNode _cvQualifier;
private SimpleReferenceType _referenceQualifier;
private BaseNode _exceptionSpec;
public FunctionType(BaseNode ReturnType, BaseNode Params, BaseNode CVQualifier, SimpleReferenceType ReferenceQualifier, BaseNode ExceptionSpec) : base(NodeType.FunctionType)
public FunctionType(BaseNode returnType, BaseNode Params, BaseNode cvQualifier, SimpleReferenceType referenceQualifier, BaseNode exceptionSpec) : base(NodeType.FunctionType)
{
this.ReturnType = ReturnType;
this.Params = Params;
this.CVQualifier = CVQualifier;
this.ReferenceQualifier = ReferenceQualifier;
this.ExceptionSpec = ExceptionSpec;
_returnType = returnType;
_params = Params;
_cvQualifier = cvQualifier;
_referenceQualifier = referenceQualifier;
_exceptionSpec = exceptionSpec;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
ReturnType.PrintLeft(Writer);
Writer.Write(" ");
_returnType.PrintLeft(writer);
writer.Write(" ");
}
public override void PrintRight(TextWriter Writer)
public override void PrintRight(TextWriter writer)
{
Writer.Write("(");
Params.Print(Writer);
Writer.Write(")");
writer.Write("(");
_params.Print(writer);
writer.Write(")");
ReturnType.PrintRight(Writer);
_returnType.PrintRight(writer);
CVQualifier.Print(Writer);
_cvQualifier.Print(writer);
if (ReferenceQualifier.Qualifier != Reference.None)
if (_referenceQualifier.Qualifier != Reference.None)
{
Writer.Write(" ");
ReferenceQualifier.PrintQualifier(Writer);
writer.Write(" ");
_referenceQualifier.PrintQualifier(writer);
}
if (ExceptionSpec != null)
if (_exceptionSpec != null)
{
Writer.Write(" ");
ExceptionSpec.Print(Writer);
writer.Write(" ");
_exceptionSpec.Print(writer);
}
}

View file

@ -4,12 +4,12 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class GlobalQualifiedName : ParentNode
{
public GlobalQualifiedName(BaseNode Child) : base(NodeType.GlobalQualifiedName, Child) { }
public GlobalQualifiedName(BaseNode child) : base(NodeType.GlobalQualifiedName, child) { }
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Writer.Write("::");
Child.Print(Writer);
writer.Write("::");
Child.Print(writer);
}
}
}

View file

@ -5,25 +5,25 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class InitListExpression : BaseNode
{
private BaseNode TypeNode;
private List<BaseNode> Nodes;
private BaseNode _typeNode;
private List<BaseNode> _nodes;
public InitListExpression(BaseNode TypeNode, List<BaseNode> Nodes) : base(NodeType.InitListExpression)
public InitListExpression(BaseNode typeNode, List<BaseNode> nodes) : base(NodeType.InitListExpression)
{
this.TypeNode = TypeNode;
this.Nodes = Nodes;
_typeNode = typeNode;
_nodes = nodes;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
if (TypeNode != null)
if (_typeNode != null)
{
TypeNode.Print(Writer);
_typeNode.Print(writer);
}
Writer.Write("{");
Writer.Write(string.Join<BaseNode>(", ", Nodes.ToArray()));
Writer.Write("}");
writer.Write("{");
writer.Write(string.Join<BaseNode>(", ", _nodes.ToArray()));
writer.Write("}");
}
}
}

View file

@ -4,19 +4,19 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class IntegerCastExpression : ParentNode
{
private string Number;
private string _number;
public IntegerCastExpression(BaseNode Type, string Number) : base(NodeType.IntegerCastExpression, Type)
public IntegerCastExpression(BaseNode type, string number) : base(NodeType.IntegerCastExpression, type)
{
this.Number = Number;
_number = number;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Writer.Write("(");
Child.Print(Writer);
Writer.Write(")");
Writer.Write(Number);
writer.Write("(");
Child.Print(writer);
writer.Write(")");
writer.Write(_number);
}
}
}

View file

@ -4,37 +4,37 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class IntegerLiteral : BaseNode
{
private string LitteralName;
private string LitteralValue;
private string _literalName;
private string _literalValue;
public IntegerLiteral(string LitteralName, string LitteralValue) : base(NodeType.IntegerLiteral)
public IntegerLiteral(string literalName, string literalValue) : base(NodeType.IntegerLiteral)
{
this.LitteralValue = LitteralValue;
this.LitteralName = LitteralName;
_literalValue = literalValue;
_literalName = literalName;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
if (LitteralName.Length > 3)
if (_literalName.Length > 3)
{
Writer.Write("(");
Writer.Write(LitteralName);
Writer.Write(")");
writer.Write("(");
writer.Write(_literalName);
writer.Write(")");
}
if (LitteralValue[0] == 'n')
if (_literalValue[0] == 'n')
{
Writer.Write("-");
Writer.Write(LitteralValue.Substring(1));
writer.Write("-");
writer.Write(_literalValue.Substring(1));
}
else
{
Writer.Write(LitteralValue);
writer.Write(_literalValue);
}
if (LitteralName.Length <= 3)
if (_literalName.Length <= 3)
{
Writer.Write(LitteralName);
writer.Write(_literalName);
}
}
}

View file

@ -4,13 +4,13 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class LiteralOperator : ParentNode
{
public LiteralOperator(BaseNode Child) : base(NodeType.LiteralOperator, Child) { }
public LiteralOperator(BaseNode child) : base(NodeType.LiteralOperator, child) { }
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Writer.Write("operator \"");
Child.PrintLeft(Writer);
Writer.Write("\"");
writer.Write("operator \"");
Child.PrintLeft(writer);
writer.Write("\"");
}
}
}

View file

@ -4,20 +4,20 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class LocalName : BaseNode
{
private BaseNode Encoding;
private BaseNode Entity;
private BaseNode _encoding;
private BaseNode _entity;
public LocalName(BaseNode Encoding, BaseNode Entity) : base(NodeType.LocalName)
public LocalName(BaseNode encoding, BaseNode entity) : base(NodeType.LocalName)
{
this.Encoding = Encoding;
this.Entity = Entity;
_encoding = encoding;
_entity = entity;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Encoding.Print(Writer);
Writer.Write("::");
Entity.Print(Writer);
_encoding.Print(writer);
writer.Write("::");
_entity.Print(writer);
}
}
}

View file

@ -4,22 +4,22 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class MemberExpression : BaseNode
{
private BaseNode LeftNode;
private string Kind;
private BaseNode RightNode;
private BaseNode _leftNode;
private string _kind;
private BaseNode _rightNode;
public MemberExpression(BaseNode LeftNode, string Kind, BaseNode RightNode) : base(NodeType.MemberExpression)
public MemberExpression(BaseNode leftNode, string kind, BaseNode rightNode) : base(NodeType.MemberExpression)
{
this.LeftNode = LeftNode;
this.Kind = Kind;
this.RightNode = RightNode;
_leftNode = leftNode;
_kind = kind;
_rightNode = rightNode;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
LeftNode.Print(Writer);
Writer.Write(Kind);
RightNode.Print(Writer);
_leftNode.Print(writer);
writer.Write(_kind);
_rightNode.Print(writer);
}
}
}

View file

@ -4,26 +4,26 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class NameType : BaseNode
{
private string NameValue;
private string _nameValue;
public NameType(string NameValue, NodeType Type) : base(Type)
public NameType(string nameValue, NodeType type) : base(type)
{
this.NameValue = NameValue;
_nameValue = nameValue;
}
public NameType(string NameValue) : base(NodeType.NameType)
public NameType(string nameValue) : base(NodeType.NameType)
{
this.NameValue = NameValue;
_nameValue = nameValue;
}
public override string GetName()
{
return NameValue;
return _nameValue;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Writer.Write(NameValue);
writer.Write(_nameValue);
}
}
}

View file

@ -4,24 +4,24 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class NameTypeWithTemplateArguments : BaseNode
{
private BaseNode Prev;
private BaseNode TemplateArgument;
private BaseNode _prev;
private BaseNode _templateArgument;
public NameTypeWithTemplateArguments(BaseNode Prev, BaseNode TemplateArgument) : base(NodeType.NameTypeWithTemplateArguments)
public NameTypeWithTemplateArguments(BaseNode prev, BaseNode templateArgument) : base(NodeType.NameTypeWithTemplateArguments)
{
this.Prev = Prev;
this.TemplateArgument = TemplateArgument;
_prev = prev;
_templateArgument = templateArgument;
}
public override string GetName()
{
return Prev.GetName();
return _prev.GetName();
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Prev.Print(Writer);
TemplateArgument.Print(Writer);
_prev.Print(writer);
_templateArgument.Print(writer);
}
}
}

View file

@ -4,23 +4,23 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class NestedName : ParentNode
{
private BaseNode Name;
private BaseNode _name;
public NestedName(BaseNode Name, BaseNode Type) : base(NodeType.NestedName, Type)
public NestedName(BaseNode name, BaseNode type) : base(NodeType.NestedName, type)
{
this.Name = Name;
_name = name;
}
public override string GetName()
{
return Name.GetName();
return _name.GetName();
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Child.Print(Writer);
Writer.Write("::");
Name.Print(Writer);
Child.Print(writer);
writer.Write("::");
_name.Print(writer);
}
}
}

View file

@ -4,51 +4,51 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class NewExpression : BaseNode
{
private NodeArray Expressions;
private BaseNode TypeNode;
private NodeArray Initializers;
private NodeArray _expressions;
private BaseNode _typeNode;
private NodeArray _initializers;
private bool IsGlobal;
private bool IsArrayExpression;
private bool _isGlobal;
private bool _isArrayExpression;
public NewExpression(NodeArray Expressions, BaseNode TypeNode, NodeArray Initializers, bool IsGlobal, bool IsArrayExpression) : base(NodeType.NewExpression)
public NewExpression(NodeArray expressions, BaseNode typeNode, NodeArray initializers, bool isGlobal, bool isArrayExpression) : base(NodeType.NewExpression)
{
this.Expressions = Expressions;
this.TypeNode = TypeNode;
this.Initializers = Initializers;
_expressions = expressions;
_typeNode = typeNode;
_initializers = initializers;
this.IsGlobal = IsGlobal;
this.IsArrayExpression = IsArrayExpression;
_isGlobal = isGlobal;
_isArrayExpression = isArrayExpression;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
if (IsGlobal)
if (_isGlobal)
{
Writer.Write("::operator ");
writer.Write("::operator ");
}
Writer.Write("new ");
writer.Write("new ");
if (IsArrayExpression)
if (_isArrayExpression)
{
Writer.Write("[] ");
writer.Write("[] ");
}
if (Expressions.Nodes.Count != 0)
if (_expressions.Nodes.Count != 0)
{
Writer.Write("(");
Expressions.Print(Writer);
Writer.Write(")");
writer.Write("(");
_expressions.Print(writer);
writer.Write(")");
}
TypeNode.Print(Writer);
_typeNode.Print(writer);
if (Initializers.Nodes.Count != 0)
if (_initializers.Nodes.Count != 0)
{
Writer.Write("(");
Initializers.Print(Writer);
Writer.Write(")");
writer.Write("(");
_initializers.Print(writer);
writer.Write(")");
}
}
}

View file

@ -7,14 +7,14 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public List<BaseNode> Nodes { get; protected set; }
public NodeArray(List<BaseNode> Nodes) : base(NodeType.NodeArray)
public NodeArray(List<BaseNode> nodes) : base(NodeType.NodeArray)
{
this.Nodes = Nodes;
Nodes = nodes;
}
public NodeArray(List<BaseNode> Nodes, NodeType Type) : base(Type)
public NodeArray(List<BaseNode> nodes, NodeType type) : base(type)
{
this.Nodes = Nodes;
Nodes = nodes;
}
public override bool IsArray()
@ -22,9 +22,9 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
return true;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Writer.Write(string.Join<BaseNode>(", ", Nodes.ToArray()));
writer.Write(string.Join<BaseNode>(", ", Nodes.ToArray()));
}
}
}

View file

@ -4,13 +4,13 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class NoexceptSpec : ParentNode
{
public NoexceptSpec(BaseNode Child) : base(NodeType.NoexceptSpec, Child) { }
public NoexceptSpec(BaseNode child) : base(NodeType.NoexceptSpec, child) { }
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Writer.Write("noexcept(");
Child.Print(Writer);
Writer.Write(")");
writer.Write("noexcept(");
Child.Print(writer);
writer.Write(")");
}
}
}

View file

@ -5,29 +5,29 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class PackedTemplateParameter : NodeArray
{
public PackedTemplateParameter(List<BaseNode> Nodes) : base(Nodes, NodeType.PackedTemplateParameter) { }
public PackedTemplateParameter(List<BaseNode> nodes) : base(nodes, NodeType.PackedTemplateParameter) { }
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
foreach (BaseNode Node in Nodes)
foreach (BaseNode node in Nodes)
{
Node.PrintLeft(Writer);
node.PrintLeft(writer);
}
}
public override void PrintRight(TextWriter Writer)
public override void PrintRight(TextWriter writer)
{
foreach (BaseNode Node in Nodes)
foreach (BaseNode node in Nodes)
{
Node.PrintLeft(Writer);
node.PrintLeft(writer);
}
}
public override bool HasRightPart()
{
foreach (BaseNode Node in Nodes)
foreach (BaseNode node in Nodes)
{
if (Node.HasRightPart())
if (node.HasRightPart())
{
return true;
}

View file

@ -4,20 +4,20 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class PackedTemplateParameterExpansion : ParentNode
{
public PackedTemplateParameterExpansion(BaseNode Child) : base(NodeType.PackedTemplateParameterExpansion, Child) {}
public PackedTemplateParameterExpansion(BaseNode child) : base(NodeType.PackedTemplateParameterExpansion, child) {}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
if (Child is PackedTemplateParameter)
{
if (((PackedTemplateParameter)Child).Nodes.Count != 0)
{
Child.Print(Writer);
Child.Print(writer);
}
}
else
{
Writer.Write("...");
writer.Write("...");
}
}
}

View file

@ -2,11 +2,11 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public abstract class ParentNode : BaseNode
{
public BaseNode Child { get; private set; }
public BaseNode Child { get; }
public ParentNode(NodeType Type, BaseNode Child) : base(Type)
public ParentNode(NodeType type, BaseNode child) : base(type)
{
this.Child = Child;
Child = child;
}
public override string GetName()

View file

@ -4,42 +4,42 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class PointerType : BaseNode
{
private BaseNode Child;
private BaseNode _child;
public PointerType(BaseNode Child) : base(NodeType.PointerType)
public PointerType(BaseNode child) : base(NodeType.PointerType)
{
this.Child = Child;
_child = child;
}
public override bool HasRightPart()
{
return Child.HasRightPart();
return _child.HasRightPart();
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Child.PrintLeft(Writer);
if (Child.IsArray())
_child.PrintLeft(writer);
if (_child.IsArray())
{
Writer.Write(" ");
writer.Write(" ");
}
if (Child.IsArray() || Child.HasFunctions())
if (_child.IsArray() || _child.HasFunctions())
{
Writer.Write("(");
writer.Write("(");
}
Writer.Write("*");
writer.Write("*");
}
public override void PrintRight(TextWriter Writer)
public override void PrintRight(TextWriter writer)
{
if (Child.IsArray() || Child.HasFunctions())
if (_child.IsArray() || _child.HasFunctions())
{
Writer.Write(")");
writer.Write(")");
}
Child.PrintRight(Writer);
_child.PrintRight(writer);
}
}
}

View file

@ -4,19 +4,19 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class PostfixExpression : ParentNode
{
private string Operator;
private string _operator;
public PostfixExpression(BaseNode Type, string Operator) : base(NodeType.PostfixExpression, Type)
public PostfixExpression(BaseNode type, string Operator) : base(NodeType.PostfixExpression, type)
{
this.Operator = Operator;
_operator = Operator;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Writer.Write("(");
Child.Print(Writer);
Writer.Write(")");
Writer.Write(Operator);
writer.Write("(");
Child.Print(writer);
writer.Write(")");
writer.Write(_operator);
}
}
}

View file

@ -4,17 +4,17 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class PostfixQualifiedType : ParentNode
{
private string PostfixQualifier;
private string _postfixQualifier;
public PostfixQualifiedType(string PostfixQualifier, BaseNode Type) : base(NodeType.PostfixQualifiedType, Type)
public PostfixQualifiedType(string postfixQualifier, BaseNode type) : base(NodeType.PostfixQualifiedType, type)
{
this.PostfixQualifier = PostfixQualifier;
_postfixQualifier = postfixQualifier;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Child.Print(Writer);
Writer.Write(PostfixQualifier);
Child.Print(writer);
writer.Write(_postfixQualifier);
}
}
}

View file

@ -4,19 +4,19 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class PrefixExpression : ParentNode
{
private string Prefix;
private string _prefix;
public PrefixExpression(string Prefix, BaseNode Child) : base(NodeType.PrefixExpression, Child)
public PrefixExpression(string prefix, BaseNode child) : base(NodeType.PrefixExpression, child)
{
this.Prefix = Prefix;
_prefix = prefix;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Writer.Write(Prefix);
Writer.Write("(");
Child.Print(Writer);
Writer.Write(")");
writer.Write(_prefix);
writer.Write("(");
Child.Print(writer);
writer.Write(")");
}
}
}

View file

@ -4,20 +4,20 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class QualifiedName : BaseNode
{
private BaseNode Qualifier;
private BaseNode Name;
private BaseNode _qualifier;
private BaseNode _name;
public QualifiedName(BaseNode Qualifier, BaseNode Name) : base(NodeType.QualifiedName)
public QualifiedName(BaseNode qualifier, BaseNode name) : base(NodeType.QualifiedName)
{
this.Qualifier = Qualifier;
this.Name = Name;
_qualifier = qualifier;
_name = name;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Qualifier.Print(Writer);
Writer.Write("::");
Name.Print(Writer);
_qualifier.Print(writer);
writer.Write("::");
_name.Print(writer);
}
}
}

View file

@ -2,7 +2,7 @@ using System.IO;
namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public enum CV
public enum Cv
{
None,
Const,
@ -17,41 +17,41 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
LValue
}
public class CVType : ParentNode
public class CvType : ParentNode
{
public CV Qualifier;
public Cv Qualifier;
public CVType(CV Qualifier, BaseNode Child) : base(NodeType.CVQualifierType, Child)
public CvType(Cv qualifier, BaseNode child) : base(NodeType.CvQualifierType, child)
{
this.Qualifier = Qualifier;
Qualifier = qualifier;
}
public void PrintQualifier(TextWriter Writer)
public void PrintQualifier(TextWriter writer)
{
if ((Qualifier & CV.Const) != 0)
if ((Qualifier & Cv.Const) != 0)
{
Writer.Write(" const");
writer.Write(" const");
}
if ((Qualifier & CV.Volatile) != 0)
if ((Qualifier & Cv.Volatile) != 0)
{
Writer.Write(" volatile");
writer.Write(" volatile");
}
if ((Qualifier & CV.Restricted) != 0)
if ((Qualifier & Cv.Restricted) != 0)
{
Writer.Write(" restrict");
writer.Write(" restrict");
}
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
if (Child != null)
{
Child.PrintLeft(Writer);
Child.PrintLeft(writer);
}
PrintQualifier(Writer);
PrintQualifier(writer);
}
public override bool HasRightPart()
@ -59,11 +59,11 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
return Child != null && Child.HasRightPart();
}
public override void PrintRight(TextWriter Writer)
public override void PrintRight(TextWriter writer)
{
if (Child != null)
{
Child.PrintRight(Writer);
Child.PrintRight(writer);
}
}
}
@ -72,36 +72,36 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public Reference Qualifier;
public SimpleReferenceType(Reference Qualifier, BaseNode Child) : base(NodeType.SimpleReferenceType, Child)
public SimpleReferenceType(Reference qualifier, BaseNode child) : base(NodeType.SimpleReferenceType, child)
{
this.Qualifier = Qualifier;
Qualifier = qualifier;
}
public void PrintQualifier(TextWriter Writer)
public void PrintQualifier(TextWriter writer)
{
if ((Qualifier & Reference.LValue) != 0)
{
Writer.Write("&");
writer.Write("&");
}
if ((Qualifier & Reference.RValue) != 0)
{
Writer.Write("&&");
writer.Write("&&");
}
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
if (Child != null)
{
Child.PrintLeft(Writer);
Child.PrintLeft(writer);
}
else if (Qualifier != Reference.None)
{
Writer.Write(" ");
writer.Write(" ");
}
PrintQualifier(Writer);
PrintQualifier(writer);
}
public override bool HasRightPart()
@ -109,11 +109,11 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
return Child != null && Child.HasRightPart();
}
public override void PrintRight(TextWriter Writer)
public override void PrintRight(TextWriter writer)
{
if (Child != null)
{
Child.PrintRight(Writer);
Child.PrintRight(writer);
}
}
}

View file

@ -4,44 +4,44 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class ReferenceType : BaseNode
{
private string Reference;
private BaseNode Child;
private string _reference;
private BaseNode _child;
public ReferenceType(string Reference, BaseNode Child) : base(NodeType.ReferenceType)
public ReferenceType(string reference, BaseNode child) : base(NodeType.ReferenceType)
{
this.Reference = Reference;
this.Child = Child;
_reference = reference;
_child = child;
}
public override bool HasRightPart()
{
return Child.HasRightPart();
return _child.HasRightPart();
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Child.PrintLeft(Writer);
_child.PrintLeft(writer);
if (Child.IsArray())
if (_child.IsArray())
{
Writer.Write(" ");
writer.Write(" ");
}
if (Child.IsArray() || Child.HasFunctions())
if (_child.IsArray() || _child.HasFunctions())
{
Writer.Write("(");
writer.Write("(");
}
Writer.Write(Reference);
writer.Write(_reference);
}
public override void PrintRight(TextWriter Writer)
public override void PrintRight(TextWriter writer)
{
if (Child.IsArray() || Child.HasFunctions())
if (_child.IsArray() || _child.HasFunctions())
{
Writer.Write(")");
writer.Write(")");
}
Child.PrintRight(Writer);
_child.PrintRight(writer);
}
}
}

View file

@ -4,17 +4,17 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class SpecialName : ParentNode
{
private string SpecialValue;
private string _specialValue;
public SpecialName(string SpecialValue, BaseNode Type) : base(NodeType.SpecialName, Type)
public SpecialName(string specialValue, BaseNode type) : base(NodeType.SpecialName, type)
{
this.SpecialValue = SpecialValue;
_specialValue = specialValue;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Writer.Write(SpecialValue);
Child.Print(Writer);
writer.Write(_specialValue);
Child.Print(writer);
}
}
}

View file

@ -11,14 +11,14 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
String,
IStream,
OStream,
IOStream,
IOStream
}
private SpecialType SpecialSubstitutionKey;
private SpecialType _specialSubstitutionKey;
public SpecialSubstitution(SpecialType SpecialSubstitutionKey) : base(NodeType.SpecialSubstitution)
public SpecialSubstitution(SpecialType specialSubstitutionKey) : base(NodeType.SpecialSubstitution)
{
this.SpecialSubstitutionKey = SpecialSubstitutionKey;
_specialSubstitutionKey = specialSubstitutionKey;
}
public void SetExtended()
@ -28,7 +28,7 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
public override string GetName()
{
switch (SpecialSubstitutionKey)
switch (_specialSubstitutionKey)
{
case SpecialType.Allocator:
return "allocator";
@ -54,7 +54,7 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
private string GetExtendedName()
{
switch (SpecialSubstitutionKey)
switch (_specialSubstitutionKey)
{
case SpecialType.Allocator:
return "std::allocator";
@ -73,16 +73,16 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
return null;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
if (Type == NodeType.ExpandedSpecialSubstitution)
{
Writer.Write(GetExtendedName());
writer.Write(GetExtendedName());
}
else
{
Writer.Write("std::");
Writer.Write(GetName());
writer.Write("std::");
writer.Write(GetName());
}
}
}

View file

@ -4,12 +4,12 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class StdQualifiedName : ParentNode
{
public StdQualifiedName(BaseNode Child) : base(NodeType.StdQualifiedName, Child) { }
public StdQualifiedName(BaseNode child) : base(NodeType.StdQualifiedName, child) { }
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Writer.Write("std::");
Child.Print(Writer);
writer.Write("std::");
Child.Print(writer);
}
}
}

View file

@ -5,22 +5,22 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class TemplateArguments : NodeArray
{
public TemplateArguments(List<BaseNode> Nodes) : base(Nodes, NodeType.TemplateArguments) { }
public TemplateArguments(List<BaseNode> nodes) : base(nodes, NodeType.TemplateArguments) { }
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
string Params = string.Join<BaseNode>(", ", Nodes.ToArray());
Writer.Write("<");
writer.Write("<");
Writer.Write(Params);
writer.Write(Params);
if (Params.EndsWith(">"))
{
Writer.Write(" ");
writer.Write(" ");
}
Writer.Write(">");
writer.Write(">");
}
}
}

View file

@ -4,17 +4,17 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class ThrowExpression : BaseNode
{
private BaseNode Expression;
private BaseNode _expression;
public ThrowExpression(BaseNode Expression) : base(NodeType.ThrowExpression)
public ThrowExpression(BaseNode expression) : base(NodeType.ThrowExpression)
{
this.Expression = Expression;
_expression = expression;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Writer.Write("throw ");
Expression.Print(Writer);
writer.Write("throw ");
_expression.Print(writer);
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -2,9 +2,9 @@ namespace Ryujinx.HLE.HOS
{
static class ErrorCode
{
public static uint MakeError(ErrorModule Module, int Code)
public static uint MakeError(ErrorModule module, int code)
{
return (uint)Module | ((uint)Code << 9);
return (uint)module | ((uint)code << 9);
}
}
}

View file

@ -8,18 +8,18 @@ namespace Ryujinx.HLE.HOS
Htcs = 4,
Ncm = 5,
Dd = 6,
Debug_Monitor = 7,
DebugMonitor = 7,
Lr = 8,
Loader = 9,
IPC_Command_Interface = 10,
IPC = 11,
IpcCommandInterface = 10,
Ipc = 11,
Pm = 15,
Ns = 16,
Socket = 17,
Htc = 18,
Ncm_Content = 20,
NcmContent = 20,
Sm = 21,
RO_Userland = 22,
RoUserland = 22,
SdMmc = 24,
Ovln = 25,
Spl = 26,
@ -41,13 +41,13 @@ namespace Ryujinx.HLE.HOS
Pcie = 120,
Friends = 121,
Bcat = 122,
SSL = 123,
Ssl = 123,
Account = 124,
News = 125,
Mii = 126,
Nfc = 127,
Am = 128,
Play_Report = 129,
PlayReport = 129,
Ahid = 130,
Qlaunch = 132,
Pcv = 133,
@ -64,23 +64,23 @@ namespace Ryujinx.HLE.HOS
Ec = 144,
ETicket = 145,
Ngc = 146,
Error_Report = 147,
ErrorReport = 147,
Apm = 148,
Profiler = 150,
Error_Upload = 151,
ErrorUpload = 151,
Audio = 153,
Npns = 154,
Npns_Http_Stream = 155,
NpnsHttpStream = 155,
Arp = 157,
Swkbd = 158,
Boot = 159,
Nfc_Mifare = 161,
Userland_Assert = 162,
NfcMifare = 161,
UserlandAssert = 162,
Fatal = 163,
Nim_Shop = 164,
NimShop = 164,
Spsm = 165,
Bgtc = 167,
Userland_Crash = 168,
UserlandCrash = 168,
SRepo = 180,
Dauth = 181,
Hid = 202,
@ -92,10 +92,10 @@ namespace Ryujinx.HLE.HOS
Web = 210,
Grc = 212,
Migration = 216,
Migration_Ldc_Server = 217,
General_Web_Applet = 800,
Wifi_Web_Auth_Applet = 809,
Whitelisted_Applet = 810,
MigrationLdcServer = 217,
GeneralWebApplet = 800,
WifiWebAuthApplet = 809,
WhitelistedApplet = 810,
ShopN = 811
}
}

View file

@ -13,116 +13,116 @@ namespace Ryujinx.HLE.HOS.Font
{
class SharedFontManager
{
private Switch Device;
private Switch _device;
private long PhysicalAddress;
private long _physicalAddress;
private string FontsPath;
private string _fontsPath;
private struct FontInfo
{
public int Offset;
public int Size;
public FontInfo(int Offset, int Size)
public FontInfo(int offset, int size)
{
this.Offset = Offset;
this.Size = Size;
Offset = offset;
Size = size;
}
}
private Dictionary<SharedFontType, FontInfo> FontData;
private Dictionary<SharedFontType, FontInfo> _fontData;
public SharedFontManager(Switch Device, long PhysicalAddress)
public SharedFontManager(Switch device, long physicalAddress)
{
this.PhysicalAddress = PhysicalAddress;
_physicalAddress = physicalAddress;
this.Device = Device;
_device = device;
FontsPath = Path.Combine(Device.FileSystem.GetSystemPath(), "fonts");
_fontsPath = Path.Combine(device.FileSystem.GetSystemPath(), "fonts");
}
public void EnsureInitialized(ContentManager ContentManager)
public void EnsureInitialized(ContentManager contentManager)
{
if (FontData == null)
if (_fontData == null)
{
Device.Memory.FillWithZeros(PhysicalAddress, Horizon.FontSize);
_device.Memory.FillWithZeros(_physicalAddress, Horizon.FontSize);
uint FontOffset = 0;
uint fontOffset = 0;
FontInfo CreateFont(string Name)
FontInfo CreateFont(string name)
{
if (ContentManager.TryGetFontTitle(Name, out long FontTitle))
if (contentManager.TryGetFontTitle(name, out long fontTitle))
{
string ContentPath = ContentManager.GetInstalledContentPath(FontTitle, StorageId.NandSystem, ContentType.Data);
string FontPath = Device.FileSystem.SwitchPathToSystemPath(ContentPath);
string contentPath = contentManager.GetInstalledContentPath(fontTitle, StorageId.NandSystem, ContentType.Data);
string fontPath = _device.FileSystem.SwitchPathToSystemPath(contentPath);
if (!string.IsNullOrWhiteSpace(FontPath))
if (!string.IsNullOrWhiteSpace(fontPath))
{
int FileIndex = 0;
int fileIndex = 0;
//Use second file in Chinese Font title for standard
if(Name == "FontChineseSimplified")
if(name == "FontChineseSimplified")
{
FileIndex = 1;
fileIndex = 1;
}
FileStream NcaFileStream = new FileStream(FontPath, FileMode.Open, FileAccess.Read);
Nca Nca = new Nca(Device.System.KeySet, NcaFileStream, false);
NcaSection RomfsSection = Nca.Sections.FirstOrDefault(x => x?.Type == SectionType.Romfs);
Romfs Romfs = new Romfs(Nca.OpenSection(RomfsSection.SectionNum, false, Device.System.FsIntegrityCheckLevel));
Stream FontFile = Romfs.OpenFile(Romfs.Files[FileIndex]);
FileStream ncaFileStream = new FileStream(fontPath, FileMode.Open, FileAccess.Read);
Nca nca = new Nca(_device.System.KeySet, ncaFileStream, false);
NcaSection romfsSection = nca.Sections.FirstOrDefault(x => x?.Type == SectionType.Romfs);
Romfs romfs = new Romfs(nca.OpenSection(romfsSection.SectionNum, false, _device.System.FsIntegrityCheckLevel));
Stream fontFile = romfs.OpenFile(romfs.Files[fileIndex]);
byte[] Data = DecryptFont(FontFile);
byte[] data = DecryptFont(fontFile);
FontInfo Info = new FontInfo((int)FontOffset, Data.Length);
FontInfo info = new FontInfo((int)fontOffset, data.Length);
WriteMagicAndSize(PhysicalAddress + FontOffset, Data.Length);
WriteMagicAndSize(_physicalAddress + fontOffset, data.Length);
FontOffset += 8;
fontOffset += 8;
uint Start = FontOffset;
uint start = fontOffset;
for (; FontOffset - Start < Data.Length; FontOffset++)
for (; fontOffset - start < data.Length; fontOffset++)
{
Device.Memory.WriteByte(PhysicalAddress + FontOffset, Data[FontOffset - Start]);
_device.Memory.WriteByte(_physicalAddress + fontOffset, data[fontOffset - start]);
}
NcaFileStream.Dispose();
Nca.Dispose();
ncaFileStream.Dispose();
nca.Dispose();
return Info;
return info;
}
}
string FontFilePath = Path.Combine(FontsPath, Name + ".ttf");
string fontFilePath = Path.Combine(_fontsPath, name + ".ttf");
if (File.Exists(FontFilePath))
if (File.Exists(fontFilePath))
{
byte[] Data = File.ReadAllBytes(FontFilePath);
byte[] data = File.ReadAllBytes(fontFilePath);
FontInfo Info = new FontInfo((int)FontOffset, Data.Length);
FontInfo info = new FontInfo((int)fontOffset, data.Length);
WriteMagicAndSize(PhysicalAddress + FontOffset, Data.Length);
WriteMagicAndSize(_physicalAddress + fontOffset, data.Length);
FontOffset += 8;
fontOffset += 8;
uint Start = FontOffset;
uint start = fontOffset;
for (; FontOffset - Start < Data.Length; FontOffset++)
for (; fontOffset - start < data.Length; fontOffset++)
{
Device.Memory.WriteByte(PhysicalAddress + FontOffset, Data[FontOffset - Start]);
_device.Memory.WriteByte(_physicalAddress + fontOffset, data[fontOffset - start]);
}
return Info;
return info;
}
else
{
throw new InvalidSystemResourceException($"Font \"{Name}.ttf\" not found. Please provide it in \"{FontsPath}\".");
throw new InvalidSystemResourceException($"Font \"{name}.ttf\" not found. Please provide it in \"{_fontsPath}\".");
}
}
FontData = new Dictionary<SharedFontType, FontInfo>()
_fontData = new Dictionary<SharedFontType, FontInfo>
{
{ SharedFontType.JapanUsEurope, CreateFont("FontStandard") },
{ SharedFontType.SimplifiedChinese, CreateFont("FontChineseSimplified") },
@ -132,39 +132,39 @@ namespace Ryujinx.HLE.HOS.Font
{ SharedFontType.NintendoEx, CreateFont("FontNintendoExtended") }
};
if (FontOffset > Horizon.FontSize)
if (fontOffset > Horizon.FontSize)
{
throw new InvalidSystemResourceException(
$"The sum of all fonts size exceed the shared memory size. " +
$"Please make sure that the fonts don't exceed {Horizon.FontSize} bytes in total. " +
$"(actual size: {FontOffset} bytes).");
$"(actual size: {fontOffset} bytes).");
}
}
}
private void WriteMagicAndSize(long Position, int Size)
private void WriteMagicAndSize(long position, int size)
{
const int DecMagic = 0x18029a7f;
const int Key = 0x49621806;
const int decMagic = 0x18029a7f;
const int key = 0x49621806;
int EncryptedSize = EndianSwap.Swap32(Size ^ Key);
int encryptedSize = EndianSwap.Swap32(size ^ key);
Device.Memory.WriteInt32(Position + 0, DecMagic);
Device.Memory.WriteInt32(Position + 4, EncryptedSize);
_device.Memory.WriteInt32(position + 0, decMagic);
_device.Memory.WriteInt32(position + 4, encryptedSize);
}
public int GetFontSize(SharedFontType FontType)
public int GetFontSize(SharedFontType fontType)
{
EnsureInitialized(Device.System.ContentManager);
EnsureInitialized(_device.System.ContentManager);
return FontData[FontType].Size;
return _fontData[fontType].Size;
}
public int GetSharedMemoryAddressOffset(SharedFontType FontType)
public int GetSharedMemoryAddressOffset(SharedFontType fontType)
{
EnsureInitialized(Device.System.ContentManager);
EnsureInitialized(_device.System.ContentManager);
return FontData[FontType].Offset + 8;
return _fontData[fontType].Offset + 8;
}
}
}

View file

@ -6,62 +6,62 @@ namespace Ryujinx.HLE.HOS
{
class GlobalStateTable
{
private ConcurrentDictionary<KProcess, IdDictionary> DictByProcess;
private ConcurrentDictionary<KProcess, IdDictionary> _dictByProcess;
public GlobalStateTable()
{
DictByProcess = new ConcurrentDictionary<KProcess, IdDictionary>();
_dictByProcess = new ConcurrentDictionary<KProcess, IdDictionary>();
}
public bool Add(KProcess Process, int Id, object Data)
public bool Add(KProcess process, int id, object data)
{
IdDictionary Dict = DictByProcess.GetOrAdd(Process, (Key) => new IdDictionary());
IdDictionary dict = _dictByProcess.GetOrAdd(process, (key) => new IdDictionary());
return Dict.Add(Id, Data);
return dict.Add(id, data);
}
public int Add(KProcess Process, object Data)
public int Add(KProcess process, object data)
{
IdDictionary Dict = DictByProcess.GetOrAdd(Process, (Key) => new IdDictionary());
IdDictionary dict = _dictByProcess.GetOrAdd(process, (key) => new IdDictionary());
return Dict.Add(Data);
return dict.Add(data);
}
public object GetData(KProcess Process, int Id)
public object GetData(KProcess process, int id)
{
if (DictByProcess.TryGetValue(Process, out IdDictionary Dict))
if (_dictByProcess.TryGetValue(process, out IdDictionary dict))
{
return Dict.GetData(Id);
return dict.GetData(id);
}
return null;
}
public T GetData<T>(KProcess Process, int Id)
public T GetData<T>(KProcess process, int id)
{
if (DictByProcess.TryGetValue(Process, out IdDictionary Dict))
if (_dictByProcess.TryGetValue(process, out IdDictionary dict))
{
return Dict.GetData<T>(Id);
return dict.GetData<T>(id);
}
return default(T);
}
public object Delete(KProcess Process, int Id)
public object Delete(KProcess process, int id)
{
if (DictByProcess.TryGetValue(Process, out IdDictionary Dict))
if (_dictByProcess.TryGetValue(process, out IdDictionary dict))
{
return Dict.Delete(Id);
return dict.Delete(id);
}
return null;
}
public ICollection<object> DeleteProcess(KProcess Process)
public ICollection<object> DeleteProcess(KProcess process)
{
if (DictByProcess.TryRemove(Process, out IdDictionary Dict))
if (_dictByProcess.TryRemove(process, out IdDictionary dict))
{
return Dict.Clear();
return dict.Clear();
}
return null;

View file

@ -8,70 +8,70 @@ namespace Ryujinx.HLE.HOS
public const string TemporaryNroSuffix = ".ryu_tmp.nro";
//http://switchbrew.org/index.php?title=Homebrew_ABI
public static void WriteHbAbiData(MemoryManager Memory, long Position, int MainThreadHandle, string SwitchPath)
public static void WriteHbAbiData(MemoryManager memory, long position, int mainThreadHandle, string switchPath)
{
//MainThreadHandle.
WriteConfigEntry(Memory, ref Position, 1, 0, MainThreadHandle);
WriteConfigEntry(memory, ref position, 1, 0, mainThreadHandle);
//NextLoadPath.
WriteConfigEntry(Memory, ref Position, 2, 0, Position + 0x200, Position + 0x400);
WriteConfigEntry(memory, ref position, 2, 0, position + 0x200, position + 0x400);
//Argv.
long ArgvPosition = Position + 0xC00;
long argvPosition = position + 0xC00;
Memory.WriteBytes(ArgvPosition, Encoding.ASCII.GetBytes(SwitchPath + "\0"));
memory.WriteBytes(argvPosition, Encoding.ASCII.GetBytes(switchPath + "\0"));
WriteConfigEntry(Memory, ref Position, 5, 0, 0, ArgvPosition);
WriteConfigEntry(memory, ref position, 5, 0, 0, argvPosition);
//AppletType.
WriteConfigEntry(Memory, ref Position, 7);
WriteConfigEntry(memory, ref position, 7);
//EndOfList.
WriteConfigEntry(Memory, ref Position, 0);
WriteConfigEntry(memory, ref position, 0);
}
private static void WriteConfigEntry(
MemoryManager Memory,
ref long Position,
int Key,
int Flags = 0,
long Value0 = 0,
long Value1 = 0)
MemoryManager memory,
ref long position,
int key,
int flags = 0,
long value0 = 0,
long value1 = 0)
{
Memory.WriteInt32(Position + 0x00, Key);
Memory.WriteInt32(Position + 0x04, Flags);
Memory.WriteInt64(Position + 0x08, Value0);
Memory.WriteInt64(Position + 0x10, Value1);
memory.WriteInt32(position + 0x00, key);
memory.WriteInt32(position + 0x04, flags);
memory.WriteInt64(position + 0x08, value0);
memory.WriteInt64(position + 0x10, value1);
Position += 0x18;
position += 0x18;
}
public static string ReadHbAbiNextLoadPath(MemoryManager Memory, long Position)
public static string ReadHbAbiNextLoadPath(MemoryManager memory, long position)
{
string FileName = null;
string fileName = null;
while (true)
{
long Key = Memory.ReadInt64(Position);
long key = memory.ReadInt64(position);
if (Key == 2)
if (key == 2)
{
long Value0 = Memory.ReadInt64(Position + 0x08);
long Value1 = Memory.ReadInt64(Position + 0x10);
long value0 = memory.ReadInt64(position + 0x08);
long value1 = memory.ReadInt64(position + 0x10);
FileName = MemoryHelper.ReadAsciiString(Memory, Value0, Value1 - Value0);
fileName = MemoryHelper.ReadAsciiString(memory, value0, value1 - value0);
break;
}
else if (Key == 0)
else if (key == 0)
{
break;
}
Position += 0x18;
position += 0x18;
}
return FileName;
return fileName;
}
}
}

View file

@ -35,34 +35,34 @@ namespace Ryujinx.HLE.HOS
internal long PrivilegedProcessLowestId { get; set; } = 1;
internal long PrivilegedProcessHighestId { get; set; } = 8;
internal Switch Device { get; private set; }
internal Switch Device { get; }
public SystemStateMgr State { get; private set; }
public SystemStateMgr State { get; }
internal bool KernelInitialized { get; private set; }
internal bool KernelInitialized { get; }
internal KResourceLimit ResourceLimit { get; private set; }
internal KResourceLimit ResourceLimit { get; }
internal KMemoryRegionManager[] MemoryRegions { get; private set; }
internal KMemoryRegionManager[] MemoryRegions { get; }
internal KMemoryBlockAllocator LargeMemoryBlockAllocator { get; private set; }
internal KMemoryBlockAllocator SmallMemoryBlockAllocator { get; private set; }
internal KMemoryBlockAllocator LargeMemoryBlockAllocator { get; }
internal KMemoryBlockAllocator SmallMemoryBlockAllocator { get; }
internal KSlabHeap UserSlabHeapPages { get; private set; }
internal KSlabHeap UserSlabHeapPages { get; }
internal KCriticalSection CriticalSection { get; private set; }
internal KCriticalSection CriticalSection { get; }
internal KScheduler Scheduler { get; private set; }
internal KScheduler Scheduler { get; }
internal KTimeManager TimeManager { get; private set; }
internal KTimeManager TimeManager { get; }
internal KSynchronization Synchronization { get; private set; }
internal KSynchronization Synchronization { get; }
internal KContextIdManager ContextIdManager { get; private set; }
internal KContextIdManager ContextIdManager { get; }
private long KipId;
private long ProcessId;
private long ThreadUid;
private long _kipId;
private long _processId;
private long _threadUid;
internal CountdownEvent ThreadCounter;
@ -72,20 +72,20 @@ namespace Ryujinx.HLE.HOS
internal bool EnableVersionChecks { get; private set; }
internal AppletStateMgr AppletState { get; private set; }
internal AppletStateMgr AppletState { get; }
internal KSharedMemory HidSharedMem { get; private set; }
internal KSharedMemory FontSharedMem { get; private set; }
internal KSharedMemory HidSharedMem { get; }
internal KSharedMemory FontSharedMem { get; }
internal SharedFontManager Font { get; private set; }
internal SharedFontManager Font { get; }
internal ContentManager ContentManager { get; private set; }
internal ContentManager ContentManager { get; }
internal KEvent VsyncEvent { get; private set; }
internal KEvent VsyncEvent { get; }
internal Keyset KeySet { get; private set; }
private bool HasStarted;
private bool _hasStarted;
public Nacp ControlData { get; set; }
@ -93,11 +93,11 @@ namespace Ryujinx.HLE.HOS
public IntegrityCheckLevel FsIntegrityCheckLevel { get; set; }
internal long HidBaseAddress { get; private set; }
internal long HidBaseAddress { get; }
public Horizon(Switch Device)
public Horizon(Switch device)
{
this.Device = Device;
Device = device;
State = new SystemStateMgr();
@ -125,8 +125,8 @@ namespace Ryujinx.HLE.HOS
ContextIdManager = new KContextIdManager();
KipId = InitialKipId;
ProcessId = InitialProcessId;
_kipId = InitialKipId;
_processId = InitialProcessId;
Scheduler.StartAutoPreemptionThread();
@ -140,90 +140,90 @@ namespace Ryujinx.HLE.HOS
//Note: This is not really correct, but with HLE of services, the only memory
//region used that is used is Application, so we can use the other ones for anything.
KMemoryRegionManager Region = MemoryRegions[(int)MemoryRegion.NvServices];
KMemoryRegionManager region = MemoryRegions[(int)MemoryRegion.NvServices];
ulong HidPa = Region.Address;
ulong FontPa = Region.Address + HidSize;
ulong hidPa = region.Address;
ulong fontPa = region.Address + HidSize;
HidBaseAddress = (long)(HidPa - DramMemoryMap.DramBase);
HidBaseAddress = (long)(hidPa - DramMemoryMap.DramBase);
KPageList HidPageList = new KPageList();
KPageList FontPageList = new KPageList();
KPageList hidPageList = new KPageList();
KPageList fontPageList = new KPageList();
HidPageList .AddRange(HidPa, HidSize / KMemoryManager.PageSize);
FontPageList.AddRange(FontPa, FontSize / KMemoryManager.PageSize);
hidPageList .AddRange(hidPa, HidSize / KMemoryManager.PageSize);
fontPageList.AddRange(fontPa, FontSize / KMemoryManager.PageSize);
HidSharedMem = new KSharedMemory(HidPageList, 0, 0, MemoryPermission.Read);
FontSharedMem = new KSharedMemory(FontPageList, 0, 0, MemoryPermission.Read);
HidSharedMem = new KSharedMemory(hidPageList, 0, 0, MemoryPermission.Read);
FontSharedMem = new KSharedMemory(fontPageList, 0, 0, MemoryPermission.Read);
AppletState = new AppletStateMgr(this);
AppletState.SetFocus(true);
Font = new SharedFontManager(Device, (long)(FontPa - DramMemoryMap.DramBase));
Font = new SharedFontManager(device, (long)(fontPa - DramMemoryMap.DramBase));
VsyncEvent = new KEvent(this);
LoadKeySet();
ContentManager = new ContentManager(Device);
ContentManager = new ContentManager(device);
}
public void LoadCart(string ExeFsDir, string RomFsFile = null)
public void LoadCart(string exeFsDir, string romFsFile = null)
{
if (RomFsFile != null)
if (romFsFile != null)
{
Device.FileSystem.LoadRomFs(RomFsFile);
Device.FileSystem.LoadRomFs(romFsFile);
}
string NpdmFileName = Path.Combine(ExeFsDir, "main.npdm");
string npdmFileName = Path.Combine(exeFsDir, "main.npdm");
Npdm MetaData = null;
Npdm metaData = null;
if (File.Exists(NpdmFileName))
if (File.Exists(npdmFileName))
{
Logger.PrintInfo(LogClass.Loader, $"Loading main.npdm...");
using (FileStream Input = new FileStream(NpdmFileName, FileMode.Open))
using (FileStream input = new FileStream(npdmFileName, FileMode.Open))
{
MetaData = new Npdm(Input);
metaData = new Npdm(input);
}
}
else
{
Logger.PrintWarning(LogClass.Loader, $"NPDM file not found, using default values!");
MetaData = GetDefaultNpdm();
metaData = GetDefaultNpdm();
}
List<IExecutable> StaticObjects = new List<IExecutable>();
List<IExecutable> staticObjects = new List<IExecutable>();
void LoadNso(string SearchPattern)
void LoadNso(string searchPattern)
{
foreach (string File in Directory.GetFiles(ExeFsDir, SearchPattern))
foreach (string file in Directory.GetFiles(exeFsDir, searchPattern))
{
if (Path.GetExtension(File) != string.Empty)
if (Path.GetExtension(file) != string.Empty)
{
continue;
}
Logger.PrintInfo(LogClass.Loader, $"Loading {Path.GetFileNameWithoutExtension(File)}...");
Logger.PrintInfo(LogClass.Loader, $"Loading {Path.GetFileNameWithoutExtension(file)}...");
using (FileStream Input = new FileStream(File, FileMode.Open))
using (FileStream input = new FileStream(file, FileMode.Open))
{
NxStaticObject StaticObject = new NxStaticObject(Input);
NxStaticObject staticObject = new NxStaticObject(input);
StaticObjects.Add(StaticObject);
staticObjects.Add(staticObject);
}
}
}
if (!MetaData.Is64Bits)
if (!metaData.Is64Bits)
{
throw new NotImplementedException("32-bit titles are unsupported!");
}
CurrentTitle = MetaData.ACI0.TitleId.ToString("x16");
CurrentTitle = metaData.Aci0.TitleId.ToString("x16");
LoadNso("rtld");
LoadNso("main");
@ -232,18 +232,18 @@ namespace Ryujinx.HLE.HOS
ContentManager.LoadEntries();
ProgramLoader.LoadStaticObjects(this, MetaData, StaticObjects.ToArray());
ProgramLoader.LoadStaticObjects(this, metaData, staticObjects.ToArray());
}
public void LoadXci(string XciFile)
public void LoadXci(string xciFile)
{
FileStream File = new FileStream(XciFile, FileMode.Open, FileAccess.Read);
FileStream file = new FileStream(xciFile, FileMode.Open, FileAccess.Read);
Xci Xci = new Xci(KeySet, File);
Xci xci = new Xci(KeySet, file);
(Nca MainNca, Nca ControlNca) = GetXciGameData(Xci);
(Nca mainNca, Nca controlNca) = GetXciGameData(xci);
if (MainNca == null)
if (mainNca == null)
{
Logger.PrintError(LogClass.Loader, "Unable to load XCI");
@ -252,23 +252,23 @@ namespace Ryujinx.HLE.HOS
ContentManager.LoadEntries();
LoadNca(MainNca, ControlNca);
LoadNca(mainNca, controlNca);
}
private (Nca Main, Nca Control) GetXciGameData(Xci Xci)
private (Nca Main, Nca Control) GetXciGameData(Xci xci)
{
if (Xci.SecurePartition == null)
if (xci.SecurePartition == null)
{
throw new InvalidDataException("Could not find XCI secure partition");
}
Nca MainNca = null;
Nca PatchNca = null;
Nca ControlNca = null;
Nca mainNca = null;
Nca patchNca = null;
Nca controlNca = null;
foreach (PfsFileEntry TicketEntry in Xci.SecurePartition.Files.Where(x => x.Name.EndsWith(".tik")))
foreach (PfsFileEntry ticketEntry in xci.SecurePartition.Files.Where(x => x.Name.EndsWith(".tik")))
{
Ticket ticket = new Ticket(Xci.SecurePartition.OpenFile(TicketEntry));
Ticket ticket = new Ticket(xci.SecurePartition.OpenFile(ticketEntry));
if (!KeySet.TitleKeys.ContainsKey(ticket.RightsId))
{
@ -276,107 +276,107 @@ namespace Ryujinx.HLE.HOS
}
}
foreach (PfsFileEntry FileEntry in Xci.SecurePartition.Files.Where(x => x.Name.EndsWith(".nca")))
foreach (PfsFileEntry fileEntry in xci.SecurePartition.Files.Where(x => x.Name.EndsWith(".nca")))
{
Stream NcaStream = Xci.SecurePartition.OpenFile(FileEntry);
Stream ncaStream = xci.SecurePartition.OpenFile(fileEntry);
Nca Nca = new Nca(KeySet, NcaStream, true);
Nca nca = new Nca(KeySet, ncaStream, true);
if (Nca.Header.ContentType == ContentType.Program)
if (nca.Header.ContentType == ContentType.Program)
{
if (Nca.Sections.Any(x => x?.Type == SectionType.Romfs))
if (nca.Sections.Any(x => x?.Type == SectionType.Romfs))
{
MainNca = Nca;
mainNca = nca;
}
else if (Nca.Sections.Any(x => x?.Type == SectionType.Bktr))
else if (nca.Sections.Any(x => x?.Type == SectionType.Bktr))
{
PatchNca = Nca;
patchNca = nca;
}
}
else if (Nca.Header.ContentType == ContentType.Control)
else if (nca.Header.ContentType == ContentType.Control)
{
ControlNca = Nca;
controlNca = nca;
}
}
if (MainNca == null)
if (mainNca == null)
{
Logger.PrintError(LogClass.Loader, "Could not find an Application NCA in the provided XCI file");
}
MainNca.SetBaseNca(PatchNca);
mainNca.SetBaseNca(patchNca);
if (ControlNca != null)
if (controlNca != null)
{
ReadControlData(ControlNca);
ReadControlData(controlNca);
}
if (PatchNca != null)
if (patchNca != null)
{
PatchNca.SetBaseNca(MainNca);
patchNca.SetBaseNca(mainNca);
return (PatchNca, ControlNca);
return (patchNca, controlNca);
}
return (MainNca, ControlNca);
return (mainNca, controlNca);
}
public void ReadControlData(Nca ControlNca)
public void ReadControlData(Nca controlNca)
{
Romfs ControlRomfs = new Romfs(ControlNca.OpenSection(0, false, FsIntegrityCheckLevel));
Romfs controlRomfs = new Romfs(controlNca.OpenSection(0, false, FsIntegrityCheckLevel));
byte[] ControlFile = ControlRomfs.GetFile("/control.nacp");
byte[] controlFile = controlRomfs.GetFile("/control.nacp");
BinaryReader Reader = new BinaryReader(new MemoryStream(ControlFile));
BinaryReader reader = new BinaryReader(new MemoryStream(controlFile));
ControlData = new Nacp(Reader);
ControlData = new Nacp(reader);
}
public void LoadNca(string NcaFile)
public void LoadNca(string ncaFile)
{
FileStream File = new FileStream(NcaFile, FileMode.Open, FileAccess.Read);
FileStream file = new FileStream(ncaFile, FileMode.Open, FileAccess.Read);
Nca Nca = new Nca(KeySet, File, true);
Nca nca = new Nca(KeySet, file, true);
LoadNca(Nca, null);
LoadNca(nca, null);
}
public void LoadNsp(string NspFile)
public void LoadNsp(string nspFile)
{
FileStream File = new FileStream(NspFile, FileMode.Open, FileAccess.Read);
FileStream file = new FileStream(nspFile, FileMode.Open, FileAccess.Read);
Pfs Nsp = new Pfs(File);
Pfs nsp = new Pfs(file);
PfsFileEntry TicketFile = Nsp.Files.FirstOrDefault(x => x.Name.EndsWith(".tik"));
PfsFileEntry ticketFile = nsp.Files.FirstOrDefault(x => x.Name.EndsWith(".tik"));
// Load title key from the NSP's ticket in case the user doesn't have a title key file
if (TicketFile != null)
if (ticketFile != null)
{
Ticket Ticket = new Ticket(Nsp.OpenFile(TicketFile));
Ticket ticket = new Ticket(nsp.OpenFile(ticketFile));
KeySet.TitleKeys[Ticket.RightsId] = Ticket.GetTitleKey(KeySet);
KeySet.TitleKeys[ticket.RightsId] = ticket.GetTitleKey(KeySet);
}
Nca MainNca = null;
Nca ControlNca = null;
Nca mainNca = null;
Nca controlNca = null;
foreach (PfsFileEntry NcaFile in Nsp.Files.Where(x => x.Name.EndsWith(".nca")))
foreach (PfsFileEntry ncaFile in nsp.Files.Where(x => x.Name.EndsWith(".nca")))
{
Nca Nca = new Nca(KeySet, Nsp.OpenFile(NcaFile), true);
Nca nca = new Nca(KeySet, nsp.OpenFile(ncaFile), true);
if (Nca.Header.ContentType == ContentType.Program)
if (nca.Header.ContentType == ContentType.Program)
{
MainNca = Nca;
mainNca = nca;
}
else if (Nca.Header.ContentType == ContentType.Control)
else if (nca.Header.ContentType == ContentType.Control)
{
ControlNca = Nca;
controlNca = nca;
}
}
if (MainNca != null)
if (mainNca != null)
{
LoadNca(MainNca, ControlNca);
LoadNca(mainNca, controlNca);
return;
}
@ -384,100 +384,100 @@ namespace Ryujinx.HLE.HOS
Logger.PrintError(LogClass.Loader, "Could not find an Application NCA in the provided NSP file");
}
public void LoadNca(Nca MainNca, Nca ControlNca)
public void LoadNca(Nca mainNca, Nca controlNca)
{
if (MainNca.Header.ContentType != ContentType.Program)
if (mainNca.Header.ContentType != ContentType.Program)
{
Logger.PrintError(LogClass.Loader, "Selected NCA is not a \"Program\" NCA");
return;
}
Stream RomfsStream = MainNca.OpenSection(ProgramPartitionType.Data, false, FsIntegrityCheckLevel);
Stream ExefsStream = MainNca.OpenSection(ProgramPartitionType.Code, false, FsIntegrityCheckLevel);
Stream romfsStream = mainNca.OpenSection(ProgramPartitionType.Data, false, FsIntegrityCheckLevel);
Stream exefsStream = mainNca.OpenSection(ProgramPartitionType.Code, false, FsIntegrityCheckLevel);
if (ExefsStream == null)
if (exefsStream == null)
{
Logger.PrintError(LogClass.Loader, "No ExeFS found in NCA");
return;
}
if (RomfsStream == null)
if (romfsStream == null)
{
Logger.PrintWarning(LogClass.Loader, "No RomFS found in NCA");
}
else
{
Device.FileSystem.SetRomFs(RomfsStream);
Device.FileSystem.SetRomFs(romfsStream);
}
Pfs Exefs = new Pfs(ExefsStream);
Pfs exefs = new Pfs(exefsStream);
Npdm MetaData = null;
Npdm metaData = null;
if (Exefs.FileExists("main.npdm"))
if (exefs.FileExists("main.npdm"))
{
Logger.PrintInfo(LogClass.Loader, "Loading main.npdm...");
MetaData = new Npdm(Exefs.OpenFile("main.npdm"));
metaData = new Npdm(exefs.OpenFile("main.npdm"));
}
else
{
Logger.PrintWarning(LogClass.Loader, $"NPDM file not found, using default values!");
MetaData = GetDefaultNpdm();
metaData = GetDefaultNpdm();
}
List<IExecutable> StaticObjects = new List<IExecutable>();
List<IExecutable> staticObjects = new List<IExecutable>();
void LoadNso(string Filename)
void LoadNso(string filename)
{
foreach (PfsFileEntry File in Exefs.Files.Where(x => x.Name.StartsWith(Filename)))
foreach (PfsFileEntry file in exefs.Files.Where(x => x.Name.StartsWith(filename)))
{
if (Path.GetExtension(File.Name) != string.Empty)
if (Path.GetExtension(file.Name) != string.Empty)
{
continue;
}
Logger.PrintInfo(LogClass.Loader, $"Loading {Filename}...");
Logger.PrintInfo(LogClass.Loader, $"Loading {filename}...");
NxStaticObject StaticObject = new NxStaticObject(Exefs.OpenFile(File));
NxStaticObject staticObject = new NxStaticObject(exefs.OpenFile(file));
StaticObjects.Add(StaticObject);
staticObjects.Add(staticObject);
}
}
Nacp ReadControlData()
{
Romfs ControlRomfs = new Romfs(ControlNca.OpenSection(0, false, FsIntegrityCheckLevel));
Romfs controlRomfs = new Romfs(controlNca.OpenSection(0, false, FsIntegrityCheckLevel));
byte[] ControlFile = ControlRomfs.GetFile("/control.nacp");
byte[] controlFile = controlRomfs.GetFile("/control.nacp");
BinaryReader Reader = new BinaryReader(new MemoryStream(ControlFile));
BinaryReader reader = new BinaryReader(new MemoryStream(controlFile));
Nacp ControlData = new Nacp(Reader);
Nacp controlData = new Nacp(reader);
CurrentTitle = ControlData.Languages[(int)State.DesiredTitleLanguage].Title;
CurrentTitle = controlData.Languages[(int)State.DesiredTitleLanguage].Title;
if (string.IsNullOrWhiteSpace(CurrentTitle))
{
CurrentTitle = ControlData.Languages.ToList().Find(x => !string.IsNullOrWhiteSpace(x.Title)).Title;
CurrentTitle = controlData.Languages.ToList().Find(x => !string.IsNullOrWhiteSpace(x.Title)).Title;
}
return ControlData;
return controlData;
}
if (ControlNca != null)
if (controlNca != null)
{
ReadControlData();
}
else
{
CurrentTitle = MetaData.ACI0.TitleId.ToString("x16");
CurrentTitle = metaData.Aci0.TitleId.ToString("x16");
}
if (!MetaData.Is64Bits)
if (!metaData.Is64Bits)
{
throw new NotImplementedException("32-bit titles are not supported!");
}
@ -489,67 +489,67 @@ namespace Ryujinx.HLE.HOS
ContentManager.LoadEntries();
ProgramLoader.LoadStaticObjects(this, MetaData, StaticObjects.ToArray());
ProgramLoader.LoadStaticObjects(this, metaData, staticObjects.ToArray());
}
public void LoadProgram(string FilePath)
public void LoadProgram(string filePath)
{
Npdm MetaData = GetDefaultNpdm();
Npdm metaData = GetDefaultNpdm();
bool IsNro = Path.GetExtension(FilePath).ToLower() == ".nro";
bool isNro = Path.GetExtension(filePath).ToLower() == ".nro";
using (FileStream Input = new FileStream(FilePath, FileMode.Open))
using (FileStream input = new FileStream(filePath, FileMode.Open))
{
IExecutable StaticObject = IsNro
? (IExecutable)new NxRelocatableObject(Input)
: (IExecutable)new NxStaticObject(Input);
IExecutable staticObject = isNro
? (IExecutable)new NxRelocatableObject(input)
: new NxStaticObject(input);
ProgramLoader.LoadStaticObjects(this, MetaData, new IExecutable[] { StaticObject });
ProgramLoader.LoadStaticObjects(this, metaData, new IExecutable[] { staticObject });
}
}
private Npdm GetDefaultNpdm()
{
Assembly Asm = Assembly.GetCallingAssembly();
Assembly asm = Assembly.GetCallingAssembly();
using (Stream NpdmStream = Asm.GetManifestResourceStream("Ryujinx.HLE.Homebrew.npdm"))
using (Stream npdmStream = asm.GetManifestResourceStream("Ryujinx.HLE.Homebrew.npdm"))
{
return new Npdm(NpdmStream);
return new Npdm(npdmStream);
}
}
public void LoadKeySet()
{
string KeyFile = null;
string TitleKeyFile = null;
string ConsoleKeyFile = null;
string keyFile = null;
string titleKeyFile = null;
string consoleKeyFile = null;
string Home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
string home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
LoadSetAtPath(Path.Combine(Home, ".switch"));
LoadSetAtPath(Path.Combine(home, ".switch"));
LoadSetAtPath(Device.FileSystem.GetSystemPath());
KeySet = ExternalKeys.ReadKeyFile(KeyFile, TitleKeyFile, ConsoleKeyFile);
KeySet = ExternalKeys.ReadKeyFile(keyFile, titleKeyFile, consoleKeyFile);
void LoadSetAtPath(string BasePath)
void LoadSetAtPath(string basePath)
{
string LocalKeyFile = Path.Combine(BasePath, "prod.keys");
string LocalTitleKeyFile = Path.Combine(BasePath, "title.keys");
string LocalConsoleKeyFile = Path.Combine(BasePath, "console.keys");
string localKeyFile = Path.Combine(basePath, "prod.keys");
string localTitleKeyFile = Path.Combine(basePath, "title.keys");
string localConsoleKeyFile = Path.Combine(basePath, "console.keys");
if (File.Exists(LocalKeyFile))
if (File.Exists(localKeyFile))
{
KeyFile = LocalKeyFile;
keyFile = localKeyFile;
}
if (File.Exists(LocalTitleKeyFile))
if (File.Exists(localTitleKeyFile))
{
TitleKeyFile = LocalTitleKeyFile;
titleKeyFile = localTitleKeyFile;
}
if (File.Exists(LocalConsoleKeyFile))
if (File.Exists(localConsoleKeyFile))
{
ConsoleKeyFile = LocalConsoleKeyFile;
consoleKeyFile = localConsoleKeyFile;
}
}
}
@ -561,22 +561,22 @@ namespace Ryujinx.HLE.HOS
internal long GetThreadUid()
{
return Interlocked.Increment(ref ThreadUid) - 1;
return Interlocked.Increment(ref _threadUid) - 1;
}
internal long GetKipId()
{
return Interlocked.Increment(ref KipId) - 1;
return Interlocked.Increment(ref _kipId) - 1;
}
internal long GetProcessId()
{
return Interlocked.Increment(ref ProcessId) - 1;
return Interlocked.Increment(ref _processId) - 1;
}
public void EnableMultiCoreScheduling()
{
if (!HasStarted)
if (!_hasStarted)
{
Scheduler.MultiCoreScheduling = true;
}
@ -584,7 +584,7 @@ namespace Ryujinx.HLE.HOS
public void DisableMultiCoreScheduling()
{
if (!HasStarted)
if (!_hasStarted)
{
Scheduler.MultiCoreScheduling = false;
}
@ -595,16 +595,16 @@ namespace Ryujinx.HLE.HOS
Dispose(true);
}
protected virtual void Dispose(bool Disposing)
protected virtual void Dispose(bool disposing)
{
if (Disposing)
if (disposing)
{
//Force all threads to exit.
lock (Processes)
{
foreach (KProcess Process in Processes.Values)
foreach (KProcess process in Processes.Values)
{
Process.StopAllThreads();
process.StopAllThreads();
}
}

View file

@ -6,56 +6,56 @@ namespace Ryujinx.HLE.HOS
{
class IdDictionary
{
private ConcurrentDictionary<int, object> Objs;
private ConcurrentDictionary<int, object> _objs;
public IdDictionary()
{
Objs = new ConcurrentDictionary<int, object>();
_objs = new ConcurrentDictionary<int, object>();
}
public bool Add(int Id, object Data)
public bool Add(int id, object data)
{
return Objs.TryAdd(Id, Data);
return _objs.TryAdd(id, data);
}
public int Add(object Data)
public int Add(object data)
{
for (int Id = 1; Id < int.MaxValue; Id++)
for (int id = 1; id < int.MaxValue; id++)
{
if (Objs.TryAdd(Id, Data))
if (_objs.TryAdd(id, data))
{
return Id;
return id;
}
}
throw new InvalidOperationException();
}
public object GetData(int Id)
public object GetData(int id)
{
if (Objs.TryGetValue(Id, out object Data))
if (_objs.TryGetValue(id, out object data))
{
return Data;
return data;
}
return null;
}
public T GetData<T>(int Id)
public T GetData<T>(int id)
{
if (Objs.TryGetValue(Id, out object Data) && Data is T)
if (_objs.TryGetValue(id, out object data) && data is T)
{
return (T)Data;
return (T)data;
}
return default(T);
}
public object Delete(int Id)
public object Delete(int id)
{
if (Objs.TryRemove(Id, out object Obj))
if (_objs.TryRemove(id, out object obj))
{
return Obj;
return obj;
}
return null;
@ -63,11 +63,11 @@ namespace Ryujinx.HLE.HOS
public ICollection<object> Clear()
{
ICollection<object> Values = Objs.Values;
ICollection<object> values = _objs.Values;
Objs.Clear();
_objs.Clear();
return Values;
return values;
}
}
}

View file

@ -4,24 +4,24 @@ namespace Ryujinx.HLE.HOS.Ipc
{
struct IpcBuffDesc
{
public long Position { get; private set; }
public long Size { get; private set; }
public int Flags { get; private set; }
public long Position { get; }
public long Size { get; }
public int Flags { get; }
public IpcBuffDesc(BinaryReader Reader)
public IpcBuffDesc(BinaryReader reader)
{
long Word0 = Reader.ReadUInt32();
long Word1 = Reader.ReadUInt32();
long Word2 = Reader.ReadUInt32();
long word0 = reader.ReadUInt32();
long word1 = reader.ReadUInt32();
long word2 = reader.ReadUInt32();
Position = Word1;
Position |= (Word2 << 4) & 0x0f00000000;
Position |= (Word2 << 34) & 0x7000000000;
Position = word1;
Position |= (word2 << 4) & 0x0f00000000;
Position |= (word2 << 34) & 0x7000000000;
Size = Word0;
Size |= (Word2 << 8) & 0xf00000000;
Size = word0;
Size |= (word2 << 8) & 0xf00000000;
Flags = (int)Word2 & 3;
Flags = (int)word2 & 3;
}
}
}

View file

@ -5,87 +5,87 @@ namespace Ryujinx.HLE.HOS.Ipc
{
class IpcHandleDesc
{
public bool HasPId { get; private set; }
public bool HasPId { get; }
public long PId { get; private set; }
public long PId { get; }
public int[] ToCopy { get; private set; }
public int[] ToMove { get; private set; }
public int[] ToCopy { get; }
public int[] ToMove { get; }
public IpcHandleDesc(BinaryReader Reader)
public IpcHandleDesc(BinaryReader reader)
{
int Word = Reader.ReadInt32();
int word = reader.ReadInt32();
HasPId = (Word & 1) != 0;
HasPId = (word & 1) != 0;
ToCopy = new int[(Word >> 1) & 0xf];
ToMove = new int[(Word >> 5) & 0xf];
ToCopy = new int[(word >> 1) & 0xf];
ToMove = new int[(word >> 5) & 0xf];
PId = HasPId ? Reader.ReadInt64() : 0;
PId = HasPId ? reader.ReadInt64() : 0;
for (int Index = 0; Index < ToCopy.Length; Index++)
for (int index = 0; index < ToCopy.Length; index++)
{
ToCopy[Index] = Reader.ReadInt32();
ToCopy[index] = reader.ReadInt32();
}
for (int Index = 0; Index < ToMove.Length; Index++)
for (int index = 0; index < ToMove.Length; index++)
{
ToMove[Index] = Reader.ReadInt32();
ToMove[index] = reader.ReadInt32();
}
}
public IpcHandleDesc(int[] Copy, int[] Move)
public IpcHandleDesc(int[] copy, int[] move)
{
ToCopy = Copy ?? throw new ArgumentNullException(nameof(Copy));
ToMove = Move ?? throw new ArgumentNullException(nameof(Move));
ToCopy = copy ?? throw new ArgumentNullException(nameof(copy));
ToMove = move ?? throw new ArgumentNullException(nameof(move));
}
public IpcHandleDesc(int[] Copy, int[] Move, long PId) : this(Copy, Move)
public IpcHandleDesc(int[] copy, int[] move, long pId) : this(copy, move)
{
this.PId = PId;
PId = pId;
HasPId = true;
}
public static IpcHandleDesc MakeCopy(params int[] Handles)
public static IpcHandleDesc MakeCopy(params int[] handles)
{
return new IpcHandleDesc(Handles, new int[0]);
return new IpcHandleDesc(handles, new int[0]);
}
public static IpcHandleDesc MakeMove(params int[] Handles)
public static IpcHandleDesc MakeMove(params int[] handles)
{
return new IpcHandleDesc(new int[0], Handles);
return new IpcHandleDesc(new int[0], handles);
}
public byte[] GetBytes()
{
using (MemoryStream MS = new MemoryStream())
using (MemoryStream ms = new MemoryStream())
{
BinaryWriter Writer = new BinaryWriter(MS);
BinaryWriter writer = new BinaryWriter(ms);
int Word = HasPId ? 1 : 0;
int word = HasPId ? 1 : 0;
Word |= (ToCopy.Length & 0xf) << 1;
Word |= (ToMove.Length & 0xf) << 5;
word |= (ToCopy.Length & 0xf) << 1;
word |= (ToMove.Length & 0xf) << 5;
Writer.Write(Word);
writer.Write(word);
if (HasPId)
{
Writer.Write((long)PId);
writer.Write(PId);
}
foreach (int Handle in ToCopy)
foreach (int handle in ToCopy)
{
Writer.Write(Handle);
writer.Write(handle);
}
foreach (int Handle in ToMove)
foreach (int handle in ToMove)
{
Writer.Write(Handle);
writer.Write(handle);
}
return MS.ToArray();
return ms.ToArray();
}
}
}

View file

@ -8,61 +8,61 @@ namespace Ryujinx.HLE.HOS.Ipc
static class IpcHandler
{
public static long IpcCall(
Switch Device,
KProcess Process,
MemoryManager Memory,
KSession Session,
IpcMessage Request,
long CmdPtr)
Switch device,
KProcess process,
MemoryManager memory,
KSession session,
IpcMessage request,
long cmdPtr)
{
IpcMessage Response = new IpcMessage();
IpcMessage response = new IpcMessage();
using (MemoryStream Raw = new MemoryStream(Request.RawData))
using (MemoryStream raw = new MemoryStream(request.RawData))
{
BinaryReader ReqReader = new BinaryReader(Raw);
BinaryReader reqReader = new BinaryReader(raw);
if (Request.Type == IpcMessageType.Request ||
Request.Type == IpcMessageType.RequestWithContext)
if (request.Type == IpcMessageType.Request ||
request.Type == IpcMessageType.RequestWithContext)
{
Response.Type = IpcMessageType.Response;
response.Type = IpcMessageType.Response;
using (MemoryStream ResMS = new MemoryStream())
using (MemoryStream resMs = new MemoryStream())
{
BinaryWriter ResWriter = new BinaryWriter(ResMS);
BinaryWriter resWriter = new BinaryWriter(resMs);
ServiceCtx Context = new ServiceCtx(
Device,
Process,
Memory,
Session,
Request,
Response,
ReqReader,
ResWriter);
ServiceCtx context = new ServiceCtx(
device,
process,
memory,
session,
request,
response,
reqReader,
resWriter);
Session.Service.CallMethod(Context);
session.Service.CallMethod(context);
Response.RawData = ResMS.ToArray();
response.RawData = resMs.ToArray();
}
}
else if (Request.Type == IpcMessageType.Control ||
Request.Type == IpcMessageType.ControlWithContext)
else if (request.Type == IpcMessageType.Control ||
request.Type == IpcMessageType.ControlWithContext)
{
long Magic = ReqReader.ReadInt64();
long CmdId = ReqReader.ReadInt64();
long magic = reqReader.ReadInt64();
long cmdId = reqReader.ReadInt64();
switch (CmdId)
switch (cmdId)
{
case 0:
{
Request = FillResponse(Response, 0, Session.Service.ConvertToDomain());
request = FillResponse(response, 0, session.Service.ConvertToDomain());
break;
}
case 3:
{
Request = FillResponse(Response, 0, 0x500);
request = FillResponse(response, 0, 0x500);
break;
}
@ -71,73 +71,73 @@ namespace Ryujinx.HLE.HOS.Ipc
case 2:
case 4:
{
int Unknown = ReqReader.ReadInt32();
int unknown = reqReader.ReadInt32();
if (Process.HandleTable.GenerateHandle(Session, out int Handle) != KernelResult.Success)
if (process.HandleTable.GenerateHandle(session, out int handle) != KernelResult.Success)
{
throw new InvalidOperationException("Out of handles!");
}
Response.HandleDesc = IpcHandleDesc.MakeMove(Handle);
response.HandleDesc = IpcHandleDesc.MakeMove(handle);
Request = FillResponse(Response, 0);
request = FillResponse(response, 0);
break;
}
default: throw new NotImplementedException(CmdId.ToString());
default: throw new NotImplementedException(cmdId.ToString());
}
}
else if (Request.Type == IpcMessageType.CloseSession)
else if (request.Type == IpcMessageType.CloseSession)
{
//TODO
}
else
{
throw new NotImplementedException(Request.Type.ToString());
throw new NotImplementedException(request.Type.ToString());
}
Memory.WriteBytes(CmdPtr, Response.GetBytes(CmdPtr));
memory.WriteBytes(cmdPtr, response.GetBytes(cmdPtr));
}
return 0;
}
private static IpcMessage FillResponse(IpcMessage Response, long Result, params int[] Values)
private static IpcMessage FillResponse(IpcMessage response, long result, params int[] values)
{
using (MemoryStream MS = new MemoryStream())
using (MemoryStream ms = new MemoryStream())
{
BinaryWriter Writer = new BinaryWriter(MS);
BinaryWriter writer = new BinaryWriter(ms);
foreach (int Value in Values)
foreach (int value in values)
{
Writer.Write(Value);
writer.Write(value);
}
return FillResponse(Response, Result, MS.ToArray());
return FillResponse(response, result, ms.ToArray());
}
}
private static IpcMessage FillResponse(IpcMessage Response, long Result, byte[] Data = null)
private static IpcMessage FillResponse(IpcMessage response, long result, byte[] data = null)
{
Response.Type = IpcMessageType.Response;
response.Type = IpcMessageType.Response;
using (MemoryStream MS = new MemoryStream())
using (MemoryStream ms = new MemoryStream())
{
BinaryWriter Writer = new BinaryWriter(MS);
BinaryWriter writer = new BinaryWriter(ms);
Writer.Write(IpcMagic.Sfco);
Writer.Write(Result);
writer.Write(IpcMagic.Sfco);
writer.Write(result);
if (Data != null)
if (data != null)
{
Writer.Write(Data);
writer.Write(data);
}
Response.RawData = MS.ToArray();
response.RawData = ms.ToArray();
}
return Response;
return response;
}
}
}

View file

@ -9,13 +9,13 @@ namespace Ryujinx.HLE.HOS.Ipc
public IpcHandleDesc HandleDesc { get; set; }
public List<IpcPtrBuffDesc> PtrBuff { get; private set; }
public List<IpcBuffDesc> SendBuff { get; private set; }
public List<IpcBuffDesc> ReceiveBuff { get; private set; }
public List<IpcBuffDesc> ExchangeBuff { get; private set; }
public List<IpcRecvListBuffDesc> RecvListBuff { get; private set; }
public List<IpcPtrBuffDesc> PtrBuff { get; }
public List<IpcBuffDesc> SendBuff { get; }
public List<IpcBuffDesc> ReceiveBuff { get; }
public List<IpcBuffDesc> ExchangeBuff { get; }
public List<IpcRecvListBuffDesc> RecvListBuff { get; }
public List<int> ObjectIds { get; private set; }
public List<int> ObjectIds { get; }
public byte[] RawData { get; set; }
@ -30,183 +30,185 @@ namespace Ryujinx.HLE.HOS.Ipc
ObjectIds = new List<int>();
}
public IpcMessage(byte[] Data, long CmdPtr) : this()
public IpcMessage(byte[] data, long cmdPtr) : this()
{
using (MemoryStream MS = new MemoryStream(Data))
using (MemoryStream ms = new MemoryStream(data))
{
BinaryReader Reader = new BinaryReader(MS);
BinaryReader reader = new BinaryReader(ms);
Initialize(Reader, CmdPtr);
Initialize(reader, cmdPtr);
}
}
private void Initialize(BinaryReader Reader, long CmdPtr)
private void Initialize(BinaryReader reader, long cmdPtr)
{
int Word0 = Reader.ReadInt32();
int Word1 = Reader.ReadInt32();
int word0 = reader.ReadInt32();
int word1 = reader.ReadInt32();
Type = (IpcMessageType)(Word0 & 0xffff);
Type = (IpcMessageType)(word0 & 0xffff);
int PtrBuffCount = (Word0 >> 16) & 0xf;
int SendBuffCount = (Word0 >> 20) & 0xf;
int RecvBuffCount = (Word0 >> 24) & 0xf;
int XchgBuffCount = (Word0 >> 28) & 0xf;
int ptrBuffCount = (word0 >> 16) & 0xf;
int sendBuffCount = (word0 >> 20) & 0xf;
int recvBuffCount = (word0 >> 24) & 0xf;
int xchgBuffCount = (word0 >> 28) & 0xf;
int RawDataSize = (Word1 >> 0) & 0x3ff;
int RecvListFlags = (Word1 >> 10) & 0xf;
bool HndDescEnable = ((Word1 >> 31) & 0x1) != 0;
int rawDataSize = (word1 >> 0) & 0x3ff;
int recvListFlags = (word1 >> 10) & 0xf;
bool hndDescEnable = ((word1 >> 31) & 0x1) != 0;
if (HndDescEnable)
if (hndDescEnable)
{
HandleDesc = new IpcHandleDesc(Reader);
HandleDesc = new IpcHandleDesc(reader);
}
for (int Index = 0; Index < PtrBuffCount; Index++)
for (int index = 0; index < ptrBuffCount; index++)
{
PtrBuff.Add(new IpcPtrBuffDesc(Reader));
PtrBuff.Add(new IpcPtrBuffDesc(reader));
}
void ReadBuff(List<IpcBuffDesc> Buff, int Count)
void ReadBuff(List<IpcBuffDesc> buff, int count)
{
for (int Index = 0; Index < Count; Index++)
for (int index = 0; index < count; index++)
{
Buff.Add(new IpcBuffDesc(Reader));
buff.Add(new IpcBuffDesc(reader));
}
}
ReadBuff(SendBuff, SendBuffCount);
ReadBuff(ReceiveBuff, RecvBuffCount);
ReadBuff(ExchangeBuff, XchgBuffCount);
ReadBuff(SendBuff, sendBuffCount);
ReadBuff(ReceiveBuff, recvBuffCount);
ReadBuff(ExchangeBuff, xchgBuffCount);
RawDataSize *= 4;
rawDataSize *= 4;
long RecvListPos = Reader.BaseStream.Position + RawDataSize;
long recvListPos = reader.BaseStream.Position + rawDataSize;
long Pad0 = GetPadSize16(Reader.BaseStream.Position + CmdPtr);
long pad0 = GetPadSize16(reader.BaseStream.Position + cmdPtr);
Reader.BaseStream.Seek(Pad0, SeekOrigin.Current);
reader.BaseStream.Seek(pad0, SeekOrigin.Current);
int RecvListCount = RecvListFlags - 2;
int recvListCount = recvListFlags - 2;
if (RecvListCount == 0)
if (recvListCount == 0)
{
RecvListCount = 1;
recvListCount = 1;
}
else if (RecvListCount < 0)
else if (recvListCount < 0)
{
RecvListCount = 0;
recvListCount = 0;
}
RawData = Reader.ReadBytes(RawDataSize);
RawData = reader.ReadBytes(rawDataSize);
Reader.BaseStream.Seek(RecvListPos, SeekOrigin.Begin);
reader.BaseStream.Seek(recvListPos, SeekOrigin.Begin);
for (int Index = 0; Index < RecvListCount; Index++)
for (int index = 0; index < recvListCount; index++)
{
RecvListBuff.Add(new IpcRecvListBuffDesc(Reader));
RecvListBuff.Add(new IpcRecvListBuffDesc(reader));
}
}
public byte[] GetBytes(long CmdPtr)
public byte[] GetBytes(long cmdPtr)
{
using (MemoryStream MS = new MemoryStream())
using (MemoryStream ms = new MemoryStream())
{
BinaryWriter Writer = new BinaryWriter(MS);
BinaryWriter writer = new BinaryWriter(ms);
int Word0;
int Word1;
int word0;
int word1;
Word0 = (int)Type;
Word0 |= (PtrBuff.Count & 0xf) << 16;
Word0 |= (SendBuff.Count & 0xf) << 20;
Word0 |= (ReceiveBuff.Count & 0xf) << 24;
Word0 |= (ExchangeBuff.Count & 0xf) << 28;
word0 = (int)Type;
word0 |= (PtrBuff.Count & 0xf) << 16;
word0 |= (SendBuff.Count & 0xf) << 20;
word0 |= (ReceiveBuff.Count & 0xf) << 24;
word0 |= (ExchangeBuff.Count & 0xf) << 28;
byte[] HandleData = new byte[0];
byte[] handleData = new byte[0];
if (HandleDesc != null)
{
HandleData = HandleDesc.GetBytes();
handleData = HandleDesc.GetBytes();
}
int DataLength = RawData?.Length ?? 0;
int dataLength = RawData?.Length ?? 0;
int Pad0 = (int)GetPadSize16(CmdPtr + 8 + HandleData.Length);
int pad0 = (int)GetPadSize16(cmdPtr + 8 + handleData.Length);
//Apparently, padding after Raw Data is 16 bytes, however when there is
//padding before Raw Data too, we need to subtract the size of this padding.
//This is the weirdest padding I've seen so far...
int Pad1 = 0x10 - Pad0;
int pad1 = 0x10 - pad0;
DataLength = (DataLength + Pad0 + Pad1) / 4;
dataLength = (dataLength + pad0 + pad1) / 4;
Word1 = DataLength & 0x3ff;
word1 = dataLength & 0x3ff;
if (HandleDesc != null)
{
Word1 |= 1 << 31;
word1 |= 1 << 31;
}
Writer.Write(Word0);
Writer.Write(Word1);
Writer.Write(HandleData);
writer.Write(word0);
writer.Write(word1);
writer.Write(handleData);
MS.Seek(Pad0, SeekOrigin.Current);
ms.Seek(pad0, SeekOrigin.Current);
if (RawData != null)
{
Writer.Write(RawData);
writer.Write(RawData);
}
Writer.Write(new byte[Pad1]);
writer.Write(new byte[pad1]);
return MS.ToArray();
return ms.ToArray();
}
}
private long GetPadSize16(long Position)
private long GetPadSize16(long position)
{
if ((Position & 0xf) != 0)
if ((position & 0xf) != 0)
{
return 0x10 - (Position & 0xf);
return 0x10 - (position & 0xf);
}
return 0;
}
public (long Position, long Size) GetBufferType0x21(int Index = 0)
// ReSharper disable once InconsistentNaming
public (long Position, long Size) GetBufferType0x21(int index = 0)
{
if (PtrBuff.Count > Index &&
PtrBuff[Index].Position != 0 &&
PtrBuff[Index].Size != 0)
if (PtrBuff.Count > index &&
PtrBuff[index].Position != 0 &&
PtrBuff[index].Size != 0)
{
return (PtrBuff[Index].Position, PtrBuff[Index].Size);
return (PtrBuff[index].Position, PtrBuff[index].Size);
}
if (SendBuff.Count > Index &&
SendBuff[Index].Position != 0 &&
SendBuff[Index].Size != 0)
if (SendBuff.Count > index &&
SendBuff[index].Position != 0 &&
SendBuff[index].Size != 0)
{
return (SendBuff[Index].Position, SendBuff[Index].Size);
return (SendBuff[index].Position, SendBuff[index].Size);
}
return (0, 0);
}
public (long Position, long Size) GetBufferType0x22(int Index = 0)
// ReSharper disable once InconsistentNaming
public (long Position, long Size) GetBufferType0x22(int index = 0)
{
if (RecvListBuff.Count > Index &&
RecvListBuff[Index].Position != 0 &&
RecvListBuff[Index].Size != 0)
if (RecvListBuff.Count > index &&
RecvListBuff[index].Position != 0 &&
RecvListBuff[index].Size != 0)
{
return (RecvListBuff[Index].Position, RecvListBuff[Index].Size);
return (RecvListBuff[index].Position, RecvListBuff[index].Size);
}
if (ReceiveBuff.Count > Index &&
ReceiveBuff[Index].Position != 0 &&
ReceiveBuff[Index].Size != 0)
if (ReceiveBuff.Count > index &&
ReceiveBuff[index].Position != 0 &&
ReceiveBuff[index].Size != 0)
{
return (ReceiveBuff[Index].Position, ReceiveBuff[Index].Size);
return (ReceiveBuff[index].Position, ReceiveBuff[index].Size);
}
return (0, 0);

View file

@ -4,23 +4,23 @@ namespace Ryujinx.HLE.HOS.Ipc
{
struct IpcPtrBuffDesc
{
public long Position { get; private set; }
public int Index { get; private set; }
public long Size { get; private set; }
public long Position { get; }
public int Index { get; }
public long Size { get; }
public IpcPtrBuffDesc(BinaryReader Reader)
public IpcPtrBuffDesc(BinaryReader reader)
{
long Word0 = Reader.ReadUInt32();
long Word1 = Reader.ReadUInt32();
long word0 = reader.ReadUInt32();
long word1 = reader.ReadUInt32();
Position = Word1;
Position |= (Word0 << 20) & 0x0f00000000;
Position |= (Word0 << 30) & 0x7000000000;
Position = word1;
Position |= (word0 << 20) & 0x0f00000000;
Position |= (word0 << 30) & 0x7000000000;
Index = ((int)Word0 >> 0) & 0x03f;
Index |= ((int)Word0 >> 3) & 0x1c0;
Index = ((int)word0 >> 0) & 0x03f;
Index |= ((int)word0 >> 3) & 0x1c0;
Size = (ushort)(Word0 >> 16);
Size = (ushort)(word0 >> 16);
}
}
}

View file

@ -4,16 +4,16 @@ namespace Ryujinx.HLE.HOS.Ipc
{
struct IpcRecvListBuffDesc
{
public long Position { get; private set; }
public long Size { get; private set; }
public long Position { get; }
public long Size { get; }
public IpcRecvListBuffDesc(BinaryReader Reader)
public IpcRecvListBuffDesc(BinaryReader reader)
{
long Value = Reader.ReadInt64();
long value = reader.ReadInt64();
Position = Value & 0xffffffffffff;
Position = value & 0xffffffffffff;
Size = (ushort)(Value >> 48);
Size = (ushort)(value >> 48);
}
}
}

View file

@ -1,4 +1,4 @@
namespace Ryujinx.HLE.HOS.Ipc
{
delegate long ServiceProcessRequest(ServiceCtx Context);
delegate long ServiceProcessRequest(ServiceCtx context);
}

View file

@ -7,7 +7,7 @@ namespace Ryujinx.HLE.HOS.Kernel
{
private class PausableThread
{
public ManualResetEvent Event { get; private set; }
public ManualResetEvent Event { get; }
public bool IsExiting { get; set; }
@ -17,49 +17,49 @@ namespace Ryujinx.HLE.HOS.Kernel
}
}
private ConcurrentDictionary<Thread, PausableThread> Threads;
private ConcurrentDictionary<Thread, PausableThread> _threads;
public HleCoreManager()
{
Threads = new ConcurrentDictionary<Thread, PausableThread>();
_threads = new ConcurrentDictionary<Thread, PausableThread>();
}
public void Set(Thread Thread)
public void Set(Thread thread)
{
GetThread(Thread).Event.Set();
GetThread(thread).Event.Set();
}
public void Reset(Thread Thread)
public void Reset(Thread thread)
{
GetThread(Thread).Event.Reset();
GetThread(thread).Event.Reset();
}
public void Wait(Thread Thread)
public void Wait(Thread thread)
{
PausableThread PausableThread = GetThread(Thread);
PausableThread pausableThread = GetThread(thread);
if (!PausableThread.IsExiting)
if (!pausableThread.IsExiting)
{
PausableThread.Event.WaitOne();
pausableThread.Event.WaitOne();
}
}
public void Exit(Thread Thread)
public void Exit(Thread thread)
{
GetThread(Thread).IsExiting = true;
GetThread(thread).IsExiting = true;
}
private PausableThread GetThread(Thread Thread)
private PausableThread GetThread(Thread thread)
{
return Threads.GetOrAdd(Thread, (Key) => new PausableThread());
return _threads.GetOrAdd(thread, (key) => new PausableThread());
}
public void RemoveThread(Thread Thread)
public void RemoveThread(Thread thread)
{
if (Threads.TryRemove(Thread, out PausableThread PausableThread))
if (_threads.TryRemove(thread, out PausableThread pausableThread))
{
PausableThread.Event.Set();
PausableThread.Event.Dispose();
pausableThread.Event.Set();
pausableThread.Event.Dispose();
}
}
}

View file

@ -14,138 +14,138 @@ namespace Ryujinx.HLE.HOS.Kernel
{
private const int Mod0 = 'M' << 0 | 'O' << 8 | 'D' << 16 | '0' << 24;
private KProcess Owner;
private KProcess _owner;
private class Image
{
public long BaseAddress { get; private set; }
public long BaseAddress { get; }
public ElfSymbol[] Symbols { get; private set; }
public ElfSymbol[] Symbols { get; }
public Image(long BaseAddress, ElfSymbol[] Symbols)
public Image(long baseAddress, ElfSymbol[] symbols)
{
this.BaseAddress = BaseAddress;
this.Symbols = Symbols;
BaseAddress = baseAddress;
Symbols = symbols;
}
}
private List<Image> Images;
private List<Image> _images;
private int Loaded;
private int _loaded;
public HleProcessDebugger(KProcess Owner)
public HleProcessDebugger(KProcess owner)
{
this.Owner = Owner;
_owner = owner;
Images = new List<Image>();
_images = new List<Image>();
}
public void PrintGuestStackTrace(CpuThreadState ThreadState)
public void PrintGuestStackTrace(CpuThreadState threadState)
{
EnsureLoaded();
StringBuilder Trace = new StringBuilder();
StringBuilder trace = new StringBuilder();
Trace.AppendLine("Guest stack trace:");
trace.AppendLine("Guest stack trace:");
void AppendTrace(long Address)
void AppendTrace(long address)
{
Image Image = GetImage(Address, out int ImageIndex);
Image image = GetImage(address, out int imageIndex);
if (Image == null || !TryGetSubName(Image, Address, out string SubName))
if (image == null || !TryGetSubName(image, address, out string subName))
{
SubName = $"Sub{Address:x16}";
subName = $"Sub{address:x16}";
}
else if (SubName.StartsWith("_Z"))
else if (subName.StartsWith("_Z"))
{
SubName = Demangler.Parse(SubName);
subName = Demangler.Parse(subName);
}
if (Image != null)
if (image != null)
{
long Offset = Address - Image.BaseAddress;
long offset = address - image.BaseAddress;
string ImageName = GetGuessedNsoNameFromIndex(ImageIndex);
string imageName = GetGuessedNsoNameFromIndex(imageIndex);
string ImageNameAndOffset = $"[{Owner.Name}] {ImageName}:0x{Offset:x8}";
string imageNameAndOffset = $"[{_owner.Name}] {imageName}:0x{offset:x8}";
Trace.AppendLine($" {ImageNameAndOffset} {SubName}");
trace.AppendLine($" {imageNameAndOffset} {subName}");
}
else
{
Trace.AppendLine($" [{Owner.Name}] ??? {SubName}");
trace.AppendLine($" [{_owner.Name}] ??? {subName}");
}
}
long FramePointer = (long)ThreadState.X29;
long framePointer = (long)threadState.X29;
while (FramePointer != 0)
while (framePointer != 0)
{
if ((FramePointer & 7) != 0 ||
!Owner.CpuMemory.IsMapped(FramePointer) ||
!Owner.CpuMemory.IsMapped(FramePointer + 8))
if ((framePointer & 7) != 0 ||
!_owner.CpuMemory.IsMapped(framePointer) ||
!_owner.CpuMemory.IsMapped(framePointer + 8))
{
break;
}
//Note: This is the return address, we need to subtract one instruction
//worth of bytes to get the branch instruction address.
AppendTrace(Owner.CpuMemory.ReadInt64(FramePointer + 8) - 4);
AppendTrace(_owner.CpuMemory.ReadInt64(framePointer + 8) - 4);
FramePointer = Owner.CpuMemory.ReadInt64(FramePointer);
framePointer = _owner.CpuMemory.ReadInt64(framePointer);
}
Logger.PrintInfo(LogClass.Cpu, Trace.ToString());
Logger.PrintInfo(LogClass.Cpu, trace.ToString());
}
private bool TryGetSubName(Image Image, long Address, out string Name)
private bool TryGetSubName(Image image, long address, out string name)
{
Address -= Image.BaseAddress;
address -= image.BaseAddress;
int Left = 0;
int Right = Image.Symbols.Length - 1;
int left = 0;
int right = image.Symbols.Length - 1;
while (Left <= Right)
while (left <= right)
{
int Size = Right - Left;
int size = right - left;
int Middle = Left + (Size >> 1);
int middle = left + (size >> 1);
ElfSymbol Symbol = Image.Symbols[Middle];
ElfSymbol symbol = image.Symbols[middle];
long EndAddr = Symbol.Value + Symbol.Size;
long endAddr = symbol.Value + symbol.Size;
if ((ulong)Address >= (ulong)Symbol.Value && (ulong)Address < (ulong)EndAddr)
if ((ulong)address >= (ulong)symbol.Value && (ulong)address < (ulong)endAddr)
{
Name = Symbol.Name;
name = symbol.Name;
return true;
}
if ((ulong)Address < (ulong)Symbol.Value)
if ((ulong)address < (ulong)symbol.Value)
{
Right = Middle - 1;
right = middle - 1;
}
else
{
Left = Middle + 1;
left = middle + 1;
}
}
Name = null;
name = null;
return false;
}
private Image GetImage(long Address, out int Index)
private Image GetImage(long address, out int index)
{
lock (Images)
lock (_images)
{
for (Index = Images.Count - 1; Index >= 0; Index--)
for (index = _images.Count - 1; index >= 0; index--)
{
if ((ulong)Address >= (ulong)Images[Index].BaseAddress)
if ((ulong)address >= (ulong)_images[index].BaseAddress)
{
return Images[Index];
return _images[index];
}
}
}
@ -153,42 +153,42 @@ namespace Ryujinx.HLE.HOS.Kernel
return null;
}
private string GetGuessedNsoNameFromIndex(int Index)
private string GetGuessedNsoNameFromIndex(int index)
{
if ((uint)Index > 11)
if ((uint)index > 11)
{
return "???";
}
if (Index == 0)
if (index == 0)
{
return "rtld";
}
else if (Index == 1)
else if (index == 1)
{
return "main";
}
else if (Index == GetImagesCount() - 1)
else if (index == GetImagesCount() - 1)
{
return "sdk";
}
else
{
return "subsdk" + (Index - 2);
return "subsdk" + (index - 2);
}
}
private int GetImagesCount()
{
lock (Images)
lock (_images)
{
return Images.Count;
return _images.Count;
}
}
private void EnsureLoaded()
{
if (Interlocked.CompareExchange(ref Loaded, 1, 0) == 0)
if (Interlocked.CompareExchange(ref _loaded, 1, 0) == 0)
{
ScanMemoryForTextSegments();
}
@ -196,115 +196,115 @@ namespace Ryujinx.HLE.HOS.Kernel
private void ScanMemoryForTextSegments()
{
ulong OldAddress = 0;
ulong Address = 0;
ulong oldAddress = 0;
ulong address = 0;
while (Address >= OldAddress)
while (address >= oldAddress)
{
KMemoryInfo Info = Owner.MemoryManager.QueryMemory(Address);
KMemoryInfo info = _owner.MemoryManager.QueryMemory(address);
if (Info.State == MemoryState.Reserved)
if (info.State == MemoryState.Reserved)
{
break;
}
if (Info.State == MemoryState.CodeStatic && Info.Permission == MemoryPermission.ReadAndExecute)
if (info.State == MemoryState.CodeStatic && info.Permission == MemoryPermission.ReadAndExecute)
{
LoadMod0Symbols(Owner.CpuMemory, (long)Info.Address);
LoadMod0Symbols(_owner.CpuMemory, (long)info.Address);
}
OldAddress = Address;
oldAddress = address;
Address = Info.Address + Info.Size;
address = info.Address + info.Size;
}
}
private void LoadMod0Symbols(MemoryManager Memory, long TextOffset)
private void LoadMod0Symbols(MemoryManager memory, long textOffset)
{
long Mod0Offset = TextOffset + Memory.ReadUInt32(TextOffset + 4);
long mod0Offset = textOffset + memory.ReadUInt32(textOffset + 4);
if (Mod0Offset < TextOffset || !Memory.IsMapped(Mod0Offset) || (Mod0Offset & 3) != 0)
if (mod0Offset < textOffset || !memory.IsMapped(mod0Offset) || (mod0Offset & 3) != 0)
{
return;
}
Dictionary<ElfDynamicTag, long> Dynamic = new Dictionary<ElfDynamicTag, long>();
Dictionary<ElfDynamicTag, long> dynamic = new Dictionary<ElfDynamicTag, long>();
int Mod0Magic = Memory.ReadInt32(Mod0Offset + 0x0);
int mod0Magic = memory.ReadInt32(mod0Offset + 0x0);
if (Mod0Magic != Mod0)
if (mod0Magic != Mod0)
{
return;
}
long DynamicOffset = Memory.ReadInt32(Mod0Offset + 0x4) + Mod0Offset;
long BssStartOffset = Memory.ReadInt32(Mod0Offset + 0x8) + Mod0Offset;
long BssEndOffset = Memory.ReadInt32(Mod0Offset + 0xc) + Mod0Offset;
long EhHdrStartOffset = Memory.ReadInt32(Mod0Offset + 0x10) + Mod0Offset;
long EhHdrEndOffset = Memory.ReadInt32(Mod0Offset + 0x14) + Mod0Offset;
long ModObjOffset = Memory.ReadInt32(Mod0Offset + 0x18) + Mod0Offset;
long dynamicOffset = memory.ReadInt32(mod0Offset + 0x4) + mod0Offset;
long bssStartOffset = memory.ReadInt32(mod0Offset + 0x8) + mod0Offset;
long bssEndOffset = memory.ReadInt32(mod0Offset + 0xc) + mod0Offset;
long ehHdrStartOffset = memory.ReadInt32(mod0Offset + 0x10) + mod0Offset;
long ehHdrEndOffset = memory.ReadInt32(mod0Offset + 0x14) + mod0Offset;
long modObjOffset = memory.ReadInt32(mod0Offset + 0x18) + mod0Offset;
while (true)
{
long TagVal = Memory.ReadInt64(DynamicOffset + 0);
long Value = Memory.ReadInt64(DynamicOffset + 8);
long tagVal = memory.ReadInt64(dynamicOffset + 0);
long value = memory.ReadInt64(dynamicOffset + 8);
DynamicOffset += 0x10;
dynamicOffset += 0x10;
ElfDynamicTag Tag = (ElfDynamicTag)TagVal;
ElfDynamicTag tag = (ElfDynamicTag)tagVal;
if (Tag == ElfDynamicTag.DT_NULL)
if (tag == ElfDynamicTag.DT_NULL)
{
break;
}
Dynamic[Tag] = Value;
dynamic[tag] = value;
}
if (!Dynamic.TryGetValue(ElfDynamicTag.DT_STRTAB, out long StrTab) ||
!Dynamic.TryGetValue(ElfDynamicTag.DT_SYMTAB, out long SymTab) ||
!Dynamic.TryGetValue(ElfDynamicTag.DT_SYMENT, out long SymEntSize))
if (!dynamic.TryGetValue(ElfDynamicTag.DT_STRTAB, out long strTab) ||
!dynamic.TryGetValue(ElfDynamicTag.DT_SYMTAB, out long symTab) ||
!dynamic.TryGetValue(ElfDynamicTag.DT_SYMENT, out long symEntSize))
{
return;
}
long StrTblAddr = TextOffset + StrTab;
long SymTblAddr = TextOffset + SymTab;
long strTblAddr = textOffset + strTab;
long symTblAddr = textOffset + symTab;
List<ElfSymbol> Symbols = new List<ElfSymbol>();
List<ElfSymbol> symbols = new List<ElfSymbol>();
while ((ulong)SymTblAddr < (ulong)StrTblAddr)
while ((ulong)symTblAddr < (ulong)strTblAddr)
{
ElfSymbol Sym = GetSymbol(Memory, SymTblAddr, StrTblAddr);
ElfSymbol sym = GetSymbol(memory, symTblAddr, strTblAddr);
Symbols.Add(Sym);
symbols.Add(sym);
SymTblAddr += SymEntSize;
symTblAddr += symEntSize;
}
lock (Images)
lock (_images)
{
Images.Add(new Image(TextOffset, Symbols.OrderBy(x => x.Value).ToArray()));
_images.Add(new Image(textOffset, symbols.OrderBy(x => x.Value).ToArray()));
}
}
private ElfSymbol GetSymbol(MemoryManager Memory, long Address, long StrTblAddr)
private ElfSymbol GetSymbol(MemoryManager memory, long address, long strTblAddr)
{
int NameIndex = Memory.ReadInt32(Address + 0);
int Info = Memory.ReadByte (Address + 4);
int Other = Memory.ReadByte (Address + 5);
int SHIdx = Memory.ReadInt16(Address + 6);
long Value = Memory.ReadInt64(Address + 8);
long Size = Memory.ReadInt64(Address + 16);
int nameIndex = memory.ReadInt32(address + 0);
int info = memory.ReadByte (address + 4);
int other = memory.ReadByte (address + 5);
int shIdx = memory.ReadInt16(address + 6);
long value = memory.ReadInt64(address + 8);
long size = memory.ReadInt64(address + 16);
string Name = string.Empty;
string name = string.Empty;
for (int Chr; (Chr = Memory.ReadByte(StrTblAddr + NameIndex++)) != 0;)
for (int chr; (chr = memory.ReadByte(strTblAddr + nameIndex++)) != 0;)
{
Name += (char)Chr;
name += (char)chr;
}
return new ElfSymbol(Name, Info, Other, SHIdx, Value, Size);
return new ElfSymbol(name, info, other, shIdx, value, size);
}
}
}

View file

@ -7,21 +7,21 @@ namespace Ryujinx.HLE.HOS.Kernel
{
private const int RoundRobinTimeQuantumMs = 10;
private int CurrentCore;
private int _currentCore;
public bool MultiCoreScheduling { get; set; }
public HleCoreManager CoreManager { get; private set; }
public HleCoreManager CoreManager { get; }
private bool KeepPreempting;
private bool _keepPreempting;
public void StartAutoPreemptionThread()
{
Thread PreemptionThread = new Thread(PreemptCurrentThread);
Thread preemptionThread = new Thread(PreemptCurrentThread);
KeepPreempting = true;
_keepPreempting = true;
PreemptionThread.Start();
preemptionThread.Start();
}
public void ContextSwitch()
@ -30,28 +30,28 @@ namespace Ryujinx.HLE.HOS.Kernel
{
if (MultiCoreScheduling)
{
int SelectedCount = 0;
int selectedCount = 0;
for (int Core = 0; Core < KScheduler.CpuCoresCount; Core++)
for (int core = 0; core < CpuCoresCount; core++)
{
KCoreContext CoreContext = CoreContexts[Core];
KCoreContext coreContext = CoreContexts[core];
if (CoreContext.ContextSwitchNeeded && (CoreContext.CurrentThread?.Context.IsCurrentThread() ?? false))
if (coreContext.ContextSwitchNeeded && (coreContext.CurrentThread?.Context.IsCurrentThread() ?? false))
{
CoreContext.ContextSwitch();
coreContext.ContextSwitch();
}
if (CoreContext.CurrentThread?.Context.IsCurrentThread() ?? false)
if (coreContext.CurrentThread?.Context.IsCurrentThread() ?? false)
{
SelectedCount++;
selectedCount++;
}
}
if (SelectedCount == 0)
if (selectedCount == 0)
{
CoreManager.Reset(Thread.CurrentThread);
}
else if (SelectedCount == 1)
else if (selectedCount == 1)
{
CoreManager.Set(Thread.CurrentThread);
}
@ -62,41 +62,41 @@ namespace Ryujinx.HLE.HOS.Kernel
}
else
{
KThread CurrentThread = CoreContexts[CurrentCore].CurrentThread;
KThread currentThread = CoreContexts[_currentCore].CurrentThread;
bool HasThreadExecuting = CurrentThread != null;
bool hasThreadExecuting = currentThread != null;
if (HasThreadExecuting)
if (hasThreadExecuting)
{
//If this is not the thread that is currently executing, we need
//to request an interrupt to allow safely starting another thread.
if (!CurrentThread.Context.IsCurrentThread())
if (!currentThread.Context.IsCurrentThread())
{
CurrentThread.Context.RequestInterrupt();
currentThread.Context.RequestInterrupt();
return;
}
CoreManager.Reset(CurrentThread.Context.Work);
CoreManager.Reset(currentThread.Context.Work);
}
//Advance current core and try picking a thread,
//keep advancing if it is null.
for (int Core = 0; Core < 4; Core++)
for (int core = 0; core < 4; core++)
{
CurrentCore = (CurrentCore + 1) % CpuCoresCount;
_currentCore = (_currentCore + 1) % CpuCoresCount;
KCoreContext CoreContext = CoreContexts[CurrentCore];
KCoreContext coreContext = CoreContexts[_currentCore];
CoreContext.UpdateCurrentThread();
coreContext.UpdateCurrentThread();
if (CoreContext.CurrentThread != null)
if (coreContext.CurrentThread != null)
{
CoreContext.CurrentThread.ClearExclusive();
coreContext.CurrentThread.ClearExclusive();
CoreManager.Set(CoreContext.CurrentThread.Context.Work);
CoreManager.Set(coreContext.CurrentThread.Context.Work);
CoreContext.CurrentThread.Context.Execute();
coreContext.CurrentThread.Context.Execute();
break;
}
@ -104,7 +104,7 @@ namespace Ryujinx.HLE.HOS.Kernel
//If nothing was running before, then we are on a "external"
//HLE thread, we don't need to wait.
if (!HasThreadExecuting)
if (!hasThreadExecuting)
{
return;
}
@ -119,13 +119,13 @@ namespace Ryujinx.HLE.HOS.Kernel
//Preempts current thread every 10 milliseconds on a round-robin fashion,
//when multi core scheduling is disabled, to try ensuring that all threads
//gets a chance to run.
while (KeepPreempting)
while (_keepPreempting)
{
lock (CoreContexts)
{
KThread CurrentThread = CoreContexts[CurrentCore].CurrentThread;
KThread currentThread = CoreContexts[_currentCore].CurrentThread;
CurrentThread?.Context.RequestInterrupt();
currentThread?.Context.RequestInterrupt();
}
PreemptThreads();
@ -134,16 +134,16 @@ namespace Ryujinx.HLE.HOS.Kernel
}
}
public void ExitThread(KThread Thread)
public void ExitThread(KThread thread)
{
Thread.Context.StopExecution();
thread.Context.StopExecution();
CoreManager.Exit(Thread.Context.Work);
CoreManager.Exit(thread.Context.Work);
}
public void RemoveThread(KThread Thread)
public void RemoveThread(KThread thread)
{
CoreManager.RemoveThread(Thread.Context.Work);
CoreManager.RemoveThread(thread.Context.Work);
}
}
}

View file

@ -9,641 +9,641 @@ namespace Ryujinx.HLE.HOS.Kernel
{
private const int HasListenersMask = 0x40000000;
private Horizon System;
private Horizon _system;
public List<KThread> CondVarThreads;
public List<KThread> ArbiterThreads;
public KAddressArbiter(Horizon System)
public KAddressArbiter(Horizon system)
{
this.System = System;
_system = system;
CondVarThreads = new List<KThread>();
ArbiterThreads = new List<KThread>();
}
public long ArbitrateLock(int OwnerHandle, long MutexAddress, int RequesterHandle)
public long ArbitrateLock(int ownerHandle, long mutexAddress, int requesterHandle)
{
KThread CurrentThread = System.Scheduler.GetCurrentThread();
KThread currentThread = _system.Scheduler.GetCurrentThread();
System.CriticalSection.Enter();
_system.CriticalSection.Enter();
CurrentThread.SignaledObj = null;
CurrentThread.ObjSyncResult = 0;
currentThread.SignaledObj = null;
currentThread.ObjSyncResult = 0;
KProcess CurrentProcess = System.Scheduler.GetCurrentProcess();
KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
if (!KernelTransfer.UserToKernelInt32(System, MutexAddress, out int MutexValue))
if (!KernelTransfer.UserToKernelInt32(_system, mutexAddress, out int mutexValue))
{
System.CriticalSection.Leave();
_system.CriticalSection.Leave();
return MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);;
return MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
}
if (MutexValue != (OwnerHandle | HasListenersMask))
if (mutexValue != (ownerHandle | HasListenersMask))
{
System.CriticalSection.Leave();
_system.CriticalSection.Leave();
return 0;
}
KThread MutexOwner = CurrentProcess.HandleTable.GetObject<KThread>(OwnerHandle);
KThread mutexOwner = currentProcess.HandleTable.GetObject<KThread>(ownerHandle);
if (MutexOwner == null)
if (mutexOwner == null)
{
System.CriticalSection.Leave();
_system.CriticalSection.Leave();
return MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle);
}
CurrentThread.MutexAddress = MutexAddress;
CurrentThread.ThreadHandleForUserMutex = RequesterHandle;
currentThread.MutexAddress = mutexAddress;
currentThread.ThreadHandleForUserMutex = requesterHandle;
MutexOwner.AddMutexWaiter(CurrentThread);
mutexOwner.AddMutexWaiter(currentThread);
CurrentThread.Reschedule(ThreadSchedState.Paused);
currentThread.Reschedule(ThreadSchedState.Paused);
System.CriticalSection.Leave();
System.CriticalSection.Enter();
_system.CriticalSection.Leave();
_system.CriticalSection.Enter();
if (CurrentThread.MutexOwner != null)
if (currentThread.MutexOwner != null)
{
CurrentThread.MutexOwner.RemoveMutexWaiter(CurrentThread);
currentThread.MutexOwner.RemoveMutexWaiter(currentThread);
}
System.CriticalSection.Leave();
_system.CriticalSection.Leave();
return (uint)CurrentThread.ObjSyncResult;
return (uint)currentThread.ObjSyncResult;
}
public long ArbitrateUnlock(long MutexAddress)
public long ArbitrateUnlock(long mutexAddress)
{
System.CriticalSection.Enter();
_system.CriticalSection.Enter();
KThread CurrentThread = System.Scheduler.GetCurrentThread();
KThread currentThread = _system.Scheduler.GetCurrentThread();
(long Result, KThread NewOwnerThread) = MutexUnlock(CurrentThread, MutexAddress);
(long result, KThread newOwnerThread) = MutexUnlock(currentThread, mutexAddress);
if (Result != 0 && NewOwnerThread != null)
if (result != 0 && newOwnerThread != null)
{
NewOwnerThread.SignaledObj = null;
NewOwnerThread.ObjSyncResult = (int)Result;
newOwnerThread.SignaledObj = null;
newOwnerThread.ObjSyncResult = (int)result;
}
System.CriticalSection.Leave();
_system.CriticalSection.Leave();
return Result;
return result;
}
public long WaitProcessWideKeyAtomic(
long MutexAddress,
long CondVarAddress,
int ThreadHandle,
long Timeout)
long mutexAddress,
long condVarAddress,
int threadHandle,
long timeout)
{
System.CriticalSection.Enter();
_system.CriticalSection.Enter();
KThread CurrentThread = System.Scheduler.GetCurrentThread();
KThread currentThread = _system.Scheduler.GetCurrentThread();
CurrentThread.SignaledObj = null;
CurrentThread.ObjSyncResult = (int)MakeError(ErrorModule.Kernel, KernelErr.Timeout);
currentThread.SignaledObj = null;
currentThread.ObjSyncResult = (int)MakeError(ErrorModule.Kernel, KernelErr.Timeout);
if (CurrentThread.ShallBeTerminated ||
CurrentThread.SchedFlags == ThreadSchedState.TerminationPending)
if (currentThread.ShallBeTerminated ||
currentThread.SchedFlags == ThreadSchedState.TerminationPending)
{
System.CriticalSection.Leave();
_system.CriticalSection.Leave();
return MakeError(ErrorModule.Kernel, KernelErr.ThreadTerminating);
}
(long Result, _) = MutexUnlock(CurrentThread, MutexAddress);
(long result, _) = MutexUnlock(currentThread, mutexAddress);
if (Result != 0)
if (result != 0)
{
System.CriticalSection.Leave();
_system.CriticalSection.Leave();
return Result;
return result;
}
CurrentThread.MutexAddress = MutexAddress;
CurrentThread.ThreadHandleForUserMutex = ThreadHandle;
CurrentThread.CondVarAddress = CondVarAddress;
currentThread.MutexAddress = mutexAddress;
currentThread.ThreadHandleForUserMutex = threadHandle;
currentThread.CondVarAddress = condVarAddress;
CondVarThreads.Add(CurrentThread);
CondVarThreads.Add(currentThread);
if (Timeout != 0)
if (timeout != 0)
{
CurrentThread.Reschedule(ThreadSchedState.Paused);
currentThread.Reschedule(ThreadSchedState.Paused);
if (Timeout > 0)
if (timeout > 0)
{
System.TimeManager.ScheduleFutureInvocation(CurrentThread, Timeout);
_system.TimeManager.ScheduleFutureInvocation(currentThread, timeout);
}
}
System.CriticalSection.Leave();
_system.CriticalSection.Leave();
if (Timeout > 0)
if (timeout > 0)
{
System.TimeManager.UnscheduleFutureInvocation(CurrentThread);
_system.TimeManager.UnscheduleFutureInvocation(currentThread);
}
System.CriticalSection.Enter();
_system.CriticalSection.Enter();
if (CurrentThread.MutexOwner != null)
if (currentThread.MutexOwner != null)
{
CurrentThread.MutexOwner.RemoveMutexWaiter(CurrentThread);
currentThread.MutexOwner.RemoveMutexWaiter(currentThread);
}
CondVarThreads.Remove(CurrentThread);
CondVarThreads.Remove(currentThread);
System.CriticalSection.Leave();
_system.CriticalSection.Leave();
return (uint)CurrentThread.ObjSyncResult;
return (uint)currentThread.ObjSyncResult;
}
private (long, KThread) MutexUnlock(KThread CurrentThread, long MutexAddress)
private (long, KThread) MutexUnlock(KThread currentThread, long mutexAddress)
{
KThread NewOwnerThread = CurrentThread.RelinquishMutex(MutexAddress, out int Count);
KThread newOwnerThread = currentThread.RelinquishMutex(mutexAddress, out int count);
int MutexValue = 0;
int mutexValue = 0;
if (NewOwnerThread != null)
if (newOwnerThread != null)
{
MutexValue = NewOwnerThread.ThreadHandleForUserMutex;
mutexValue = newOwnerThread.ThreadHandleForUserMutex;
if (Count >= 2)
if (count >= 2)
{
MutexValue |= HasListenersMask;
mutexValue |= HasListenersMask;
}
NewOwnerThread.SignaledObj = null;
NewOwnerThread.ObjSyncResult = 0;
newOwnerThread.SignaledObj = null;
newOwnerThread.ObjSyncResult = 0;
NewOwnerThread.ReleaseAndResume();
newOwnerThread.ReleaseAndResume();
}
long Result = 0;
long result = 0;
if (!KernelTransfer.KernelToUserInt32(System, MutexAddress, MutexValue))
if (!KernelTransfer.KernelToUserInt32(_system, mutexAddress, mutexValue))
{
Result = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
result = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
}
return (Result, NewOwnerThread);
return (result, newOwnerThread);
}
public void SignalProcessWideKey(long Address, int Count)
public void SignalProcessWideKey(long address, int count)
{
Queue<KThread> SignaledThreads = new Queue<KThread>();
Queue<KThread> signaledThreads = new Queue<KThread>();
System.CriticalSection.Enter();
_system.CriticalSection.Enter();
IOrderedEnumerable<KThread> SortedThreads = CondVarThreads.OrderBy(x => x.DynamicPriority);
IOrderedEnumerable<KThread> sortedThreads = CondVarThreads.OrderBy(x => x.DynamicPriority);
foreach (KThread Thread in SortedThreads.Where(x => x.CondVarAddress == Address))
foreach (KThread thread in sortedThreads.Where(x => x.CondVarAddress == address))
{
TryAcquireMutex(Thread);
TryAcquireMutex(thread);
SignaledThreads.Enqueue(Thread);
signaledThreads.Enqueue(thread);
//If the count is <= 0, we should signal all threads waiting.
if (Count >= 1 && --Count == 0)
if (count >= 1 && --count == 0)
{
break;
}
}
while (SignaledThreads.TryDequeue(out KThread Thread))
while (signaledThreads.TryDequeue(out KThread thread))
{
CondVarThreads.Remove(Thread);
CondVarThreads.Remove(thread);
}
System.CriticalSection.Leave();
_system.CriticalSection.Leave();
}
private KThread TryAcquireMutex(KThread Requester)
private KThread TryAcquireMutex(KThread requester)
{
long Address = Requester.MutexAddress;
long address = requester.MutexAddress;
KProcess CurrentProcess = System.Scheduler.GetCurrentProcess();
KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
CurrentProcess.CpuMemory.SetExclusive(0, Address);
currentProcess.CpuMemory.SetExclusive(0, address);
if (!KernelTransfer.UserToKernelInt32(System, Address, out int MutexValue))
if (!KernelTransfer.UserToKernelInt32(_system, address, out int mutexValue))
{
//Invalid address.
CurrentProcess.CpuMemory.ClearExclusive(0);
currentProcess.CpuMemory.ClearExclusive(0);
Requester.SignaledObj = null;
Requester.ObjSyncResult = (int)MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
requester.SignaledObj = null;
requester.ObjSyncResult = (int)MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
return null;
}
while (true)
{
if (CurrentProcess.CpuMemory.TestExclusive(0, Address))
if (currentProcess.CpuMemory.TestExclusive(0, address))
{
if (MutexValue != 0)
if (mutexValue != 0)
{
//Update value to indicate there is a mutex waiter now.
CurrentProcess.CpuMemory.WriteInt32(Address, MutexValue | HasListenersMask);
currentProcess.CpuMemory.WriteInt32(address, mutexValue | HasListenersMask);
}
else
{
//No thread owning the mutex, assign to requesting thread.
CurrentProcess.CpuMemory.WriteInt32(Address, Requester.ThreadHandleForUserMutex);
currentProcess.CpuMemory.WriteInt32(address, requester.ThreadHandleForUserMutex);
}
CurrentProcess.CpuMemory.ClearExclusiveForStore(0);
currentProcess.CpuMemory.ClearExclusiveForStore(0);
break;
}
CurrentProcess.CpuMemory.SetExclusive(0, Address);
currentProcess.CpuMemory.SetExclusive(0, address);
MutexValue = CurrentProcess.CpuMemory.ReadInt32(Address);
mutexValue = currentProcess.CpuMemory.ReadInt32(address);
}
if (MutexValue == 0)
if (mutexValue == 0)
{
//We now own the mutex.
Requester.SignaledObj = null;
Requester.ObjSyncResult = 0;
requester.SignaledObj = null;
requester.ObjSyncResult = 0;
Requester.ReleaseAndResume();
requester.ReleaseAndResume();
return null;
}
MutexValue &= ~HasListenersMask;
mutexValue &= ~HasListenersMask;
KThread MutexOwner = CurrentProcess.HandleTable.GetObject<KThread>(MutexValue);
KThread mutexOwner = currentProcess.HandleTable.GetObject<KThread>(mutexValue);
if (MutexOwner != null)
if (mutexOwner != null)
{
//Mutex already belongs to another thread, wait for it.
MutexOwner.AddMutexWaiter(Requester);
mutexOwner.AddMutexWaiter(requester);
}
else
{
//Invalid mutex owner.
Requester.SignaledObj = null;
Requester.ObjSyncResult = (int)MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle);
requester.SignaledObj = null;
requester.ObjSyncResult = (int)MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle);
Requester.ReleaseAndResume();
requester.ReleaseAndResume();
}
return MutexOwner;
return mutexOwner;
}
public long WaitForAddressIfEqual(long Address, int Value, long Timeout)
public long WaitForAddressIfEqual(long address, int value, long timeout)
{
KThread CurrentThread = System.Scheduler.GetCurrentThread();
KThread currentThread = _system.Scheduler.GetCurrentThread();
System.CriticalSection.Enter();
_system.CriticalSection.Enter();
if (CurrentThread.ShallBeTerminated ||
CurrentThread.SchedFlags == ThreadSchedState.TerminationPending)
if (currentThread.ShallBeTerminated ||
currentThread.SchedFlags == ThreadSchedState.TerminationPending)
{
System.CriticalSection.Leave();
_system.CriticalSection.Leave();
return MakeError(ErrorModule.Kernel, KernelErr.ThreadTerminating);
}
CurrentThread.SignaledObj = null;
CurrentThread.ObjSyncResult = (int)MakeError(ErrorModule.Kernel, KernelErr.Timeout);
currentThread.SignaledObj = null;
currentThread.ObjSyncResult = (int)MakeError(ErrorModule.Kernel, KernelErr.Timeout);
if (!KernelTransfer.UserToKernelInt32(System, Address, out int CurrentValue))
if (!KernelTransfer.UserToKernelInt32(_system, address, out int currentValue))
{
System.CriticalSection.Leave();
_system.CriticalSection.Leave();
return MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
}
if (CurrentValue == Value)
if (currentValue == value)
{
if (Timeout == 0)
if (timeout == 0)
{
System.CriticalSection.Leave();
_system.CriticalSection.Leave();
return MakeError(ErrorModule.Kernel, KernelErr.Timeout);
}
CurrentThread.MutexAddress = Address;
CurrentThread.WaitingInArbitration = true;
currentThread.MutexAddress = address;
currentThread.WaitingInArbitration = true;
InsertSortedByPriority(ArbiterThreads, CurrentThread);
InsertSortedByPriority(ArbiterThreads, currentThread);
CurrentThread.Reschedule(ThreadSchedState.Paused);
currentThread.Reschedule(ThreadSchedState.Paused);
if (Timeout > 0)
if (timeout > 0)
{
System.TimeManager.ScheduleFutureInvocation(CurrentThread, Timeout);
_system.TimeManager.ScheduleFutureInvocation(currentThread, timeout);
}
System.CriticalSection.Leave();
_system.CriticalSection.Leave();
if (Timeout > 0)
if (timeout > 0)
{
System.TimeManager.UnscheduleFutureInvocation(CurrentThread);
_system.TimeManager.UnscheduleFutureInvocation(currentThread);
}
System.CriticalSection.Enter();
_system.CriticalSection.Enter();
if (CurrentThread.WaitingInArbitration)
if (currentThread.WaitingInArbitration)
{
ArbiterThreads.Remove(CurrentThread);
ArbiterThreads.Remove(currentThread);
CurrentThread.WaitingInArbitration = false;
currentThread.WaitingInArbitration = false;
}
System.CriticalSection.Leave();
_system.CriticalSection.Leave();
return CurrentThread.ObjSyncResult;
return currentThread.ObjSyncResult;
}
System.CriticalSection.Leave();
_system.CriticalSection.Leave();
return MakeError(ErrorModule.Kernel, KernelErr.InvalidState);
}
public long WaitForAddressIfLessThan(long Address, int Value, bool ShouldDecrement, long Timeout)
public long WaitForAddressIfLessThan(long address, int value, bool shouldDecrement, long timeout)
{
KThread CurrentThread = System.Scheduler.GetCurrentThread();
KThread currentThread = _system.Scheduler.GetCurrentThread();
System.CriticalSection.Enter();
_system.CriticalSection.Enter();
if (CurrentThread.ShallBeTerminated ||
CurrentThread.SchedFlags == ThreadSchedState.TerminationPending)
if (currentThread.ShallBeTerminated ||
currentThread.SchedFlags == ThreadSchedState.TerminationPending)
{
System.CriticalSection.Leave();
_system.CriticalSection.Leave();
return MakeError(ErrorModule.Kernel, KernelErr.ThreadTerminating);
}
CurrentThread.SignaledObj = null;
CurrentThread.ObjSyncResult = (int)MakeError(ErrorModule.Kernel, KernelErr.Timeout);
currentThread.SignaledObj = null;
currentThread.ObjSyncResult = (int)MakeError(ErrorModule.Kernel, KernelErr.Timeout);
KProcess CurrentProcess = System.Scheduler.GetCurrentProcess();
KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
//If ShouldDecrement is true, do atomic decrement of the value at Address.
CurrentProcess.CpuMemory.SetExclusive(0, Address);
currentProcess.CpuMemory.SetExclusive(0, address);
if (!KernelTransfer.UserToKernelInt32(System, Address, out int CurrentValue))
if (!KernelTransfer.UserToKernelInt32(_system, address, out int currentValue))
{
System.CriticalSection.Leave();
_system.CriticalSection.Leave();
return MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
}
if (ShouldDecrement)
if (shouldDecrement)
{
while (CurrentValue < Value)
while (currentValue < value)
{
if (CurrentProcess.CpuMemory.TestExclusive(0, Address))
if (currentProcess.CpuMemory.TestExclusive(0, address))
{
CurrentProcess.CpuMemory.WriteInt32(Address, CurrentValue - 1);
currentProcess.CpuMemory.WriteInt32(address, currentValue - 1);
CurrentProcess.CpuMemory.ClearExclusiveForStore(0);
currentProcess.CpuMemory.ClearExclusiveForStore(0);
break;
}
CurrentProcess.CpuMemory.SetExclusive(0, Address);
currentProcess.CpuMemory.SetExclusive(0, address);
CurrentValue = CurrentProcess.CpuMemory.ReadInt32(Address);
currentValue = currentProcess.CpuMemory.ReadInt32(address);
}
}
CurrentProcess.CpuMemory.ClearExclusive(0);
currentProcess.CpuMemory.ClearExclusive(0);
if (CurrentValue < Value)
if (currentValue < value)
{
if (Timeout == 0)
if (timeout == 0)
{
System.CriticalSection.Leave();
_system.CriticalSection.Leave();
return MakeError(ErrorModule.Kernel, KernelErr.Timeout);
}
CurrentThread.MutexAddress = Address;
CurrentThread.WaitingInArbitration = true;
currentThread.MutexAddress = address;
currentThread.WaitingInArbitration = true;
InsertSortedByPriority(ArbiterThreads, CurrentThread);
InsertSortedByPriority(ArbiterThreads, currentThread);
CurrentThread.Reschedule(ThreadSchedState.Paused);
currentThread.Reschedule(ThreadSchedState.Paused);
if (Timeout > 0)
if (timeout > 0)
{
System.TimeManager.ScheduleFutureInvocation(CurrentThread, Timeout);
_system.TimeManager.ScheduleFutureInvocation(currentThread, timeout);
}
System.CriticalSection.Leave();
_system.CriticalSection.Leave();
if (Timeout > 0)
if (timeout > 0)
{
System.TimeManager.UnscheduleFutureInvocation(CurrentThread);
_system.TimeManager.UnscheduleFutureInvocation(currentThread);
}
System.CriticalSection.Enter();
_system.CriticalSection.Enter();
if (CurrentThread.WaitingInArbitration)
if (currentThread.WaitingInArbitration)
{
ArbiterThreads.Remove(CurrentThread);
ArbiterThreads.Remove(currentThread);
CurrentThread.WaitingInArbitration = false;
currentThread.WaitingInArbitration = false;
}
System.CriticalSection.Leave();
_system.CriticalSection.Leave();
return CurrentThread.ObjSyncResult;
return currentThread.ObjSyncResult;
}
System.CriticalSection.Leave();
_system.CriticalSection.Leave();
return MakeError(ErrorModule.Kernel, KernelErr.InvalidState);
}
private void InsertSortedByPriority(List<KThread> Threads, KThread Thread)
private void InsertSortedByPriority(List<KThread> threads, KThread thread)
{
int NextIndex = -1;
int nextIndex = -1;
for (int Index = 0; Index < Threads.Count; Index++)
for (int index = 0; index < threads.Count; index++)
{
if (Threads[Index].DynamicPriority > Thread.DynamicPriority)
if (threads[index].DynamicPriority > thread.DynamicPriority)
{
NextIndex = Index;
nextIndex = index;
break;
}
}
if (NextIndex != -1)
if (nextIndex != -1)
{
Threads.Insert(NextIndex, Thread);
threads.Insert(nextIndex, thread);
}
else
{
Threads.Add(Thread);
threads.Add(thread);
}
}
public long Signal(long Address, int Count)
public long Signal(long address, int count)
{
System.CriticalSection.Enter();
_system.CriticalSection.Enter();
WakeArbiterThreads(Address, Count);
WakeArbiterThreads(address, count);
System.CriticalSection.Leave();
_system.CriticalSection.Leave();
return 0;
}
public long SignalAndIncrementIfEqual(long Address, int Value, int Count)
public long SignalAndIncrementIfEqual(long address, int value, int count)
{
System.CriticalSection.Enter();
_system.CriticalSection.Enter();
KProcess CurrentProcess = System.Scheduler.GetCurrentProcess();
KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
CurrentProcess.CpuMemory.SetExclusive(0, Address);
currentProcess.CpuMemory.SetExclusive(0, address);
if (!KernelTransfer.UserToKernelInt32(System, Address, out int CurrentValue))
if (!KernelTransfer.UserToKernelInt32(_system, address, out int currentValue))
{
System.CriticalSection.Leave();
_system.CriticalSection.Leave();
return MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
}
while (CurrentValue == Value)
while (currentValue == value)
{
if (CurrentProcess.CpuMemory.TestExclusive(0, Address))
if (currentProcess.CpuMemory.TestExclusive(0, address))
{
CurrentProcess.CpuMemory.WriteInt32(Address, CurrentValue + 1);
currentProcess.CpuMemory.WriteInt32(address, currentValue + 1);
CurrentProcess.CpuMemory.ClearExclusiveForStore(0);
currentProcess.CpuMemory.ClearExclusiveForStore(0);
break;
}
CurrentProcess.CpuMemory.SetExclusive(0, Address);
currentProcess.CpuMemory.SetExclusive(0, address);
CurrentValue = CurrentProcess.CpuMemory.ReadInt32(Address);
currentValue = currentProcess.CpuMemory.ReadInt32(address);
}
CurrentProcess.CpuMemory.ClearExclusive(0);
currentProcess.CpuMemory.ClearExclusive(0);
if (CurrentValue != Value)
if (currentValue != value)
{
System.CriticalSection.Leave();
_system.CriticalSection.Leave();
return MakeError(ErrorModule.Kernel, KernelErr.InvalidState);
}
WakeArbiterThreads(Address, Count);
WakeArbiterThreads(address, count);
System.CriticalSection.Leave();
_system.CriticalSection.Leave();
return 0;
}
public long SignalAndModifyIfEqual(long Address, int Value, int Count)
public long SignalAndModifyIfEqual(long address, int value, int count)
{
System.CriticalSection.Enter();
_system.CriticalSection.Enter();
int Offset;
int offset;
//The value is decremented if the number of threads waiting is less
//or equal to the Count of threads to be signaled, or Count is zero
//or negative. It is incremented if there are no threads waiting.
int WaitingCount = 0;
int waitingCount = 0;
foreach (KThread Thread in ArbiterThreads.Where(x => x.MutexAddress == Address))
foreach (KThread thread in ArbiterThreads.Where(x => x.MutexAddress == address))
{
if (++WaitingCount > Count)
if (++waitingCount > count)
{
break;
}
}
if (WaitingCount > 0)
if (waitingCount > 0)
{
Offset = WaitingCount <= Count || Count <= 0 ? -1 : 0;
offset = waitingCount <= count || count <= 0 ? -1 : 0;
}
else
{
Offset = 1;
offset = 1;
}
KProcess CurrentProcess = System.Scheduler.GetCurrentProcess();
KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
CurrentProcess.CpuMemory.SetExclusive(0, Address);
currentProcess.CpuMemory.SetExclusive(0, address);
if (!KernelTransfer.UserToKernelInt32(System, Address, out int CurrentValue))
if (!KernelTransfer.UserToKernelInt32(_system, address, out int currentValue))
{
System.CriticalSection.Leave();
_system.CriticalSection.Leave();
return MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
}
while (CurrentValue == Value)
while (currentValue == value)
{
if (CurrentProcess.CpuMemory.TestExclusive(0, Address))
if (currentProcess.CpuMemory.TestExclusive(0, address))
{
CurrentProcess.CpuMemory.WriteInt32(Address, CurrentValue + Offset);
currentProcess.CpuMemory.WriteInt32(address, currentValue + offset);
CurrentProcess.CpuMemory.ClearExclusiveForStore(0);
currentProcess.CpuMemory.ClearExclusiveForStore(0);
break;
}
CurrentProcess.CpuMemory.SetExclusive(0, Address);
currentProcess.CpuMemory.SetExclusive(0, address);
CurrentValue = CurrentProcess.CpuMemory.ReadInt32(Address);
currentValue = currentProcess.CpuMemory.ReadInt32(address);
}
CurrentProcess.CpuMemory.ClearExclusive(0);
currentProcess.CpuMemory.ClearExclusive(0);
if (CurrentValue != Value)
if (currentValue != value)
{
System.CriticalSection.Leave();
_system.CriticalSection.Leave();
return MakeError(ErrorModule.Kernel, KernelErr.InvalidState);
}
WakeArbiterThreads(Address, Count);
WakeArbiterThreads(address, count);
System.CriticalSection.Leave();
_system.CriticalSection.Leave();
return 0;
}
private void WakeArbiterThreads(long Address, int Count)
private void WakeArbiterThreads(long address, int count)
{
Queue<KThread> SignaledThreads = new Queue<KThread>();
Queue<KThread> signaledThreads = new Queue<KThread>();
foreach (KThread Thread in ArbiterThreads.Where(x => x.MutexAddress == Address))
foreach (KThread thread in ArbiterThreads.Where(x => x.MutexAddress == address))
{
SignaledThreads.Enqueue(Thread);
signaledThreads.Enqueue(thread);
//If the count is <= 0, we should signal all threads waiting.
if (Count >= 1 && --Count == 0)
if (count >= 1 && --count == 0)
{
break;
}
}
while (SignaledThreads.TryDequeue(out KThread Thread))
while (signaledThreads.TryDequeue(out KThread thread))
{
Thread.SignaledObj = null;
Thread.ObjSyncResult = 0;
thread.SignaledObj = null;
thread.ObjSyncResult = 0;
Thread.ReleaseAndResume();
thread.ReleaseAndResume();
Thread.WaitingInArbitration = false;
thread.WaitingInArbitration = false;
ArbiterThreads.Remove(Thread);
ArbiterThreads.Remove(thread);
}
}
}

View file

@ -4,14 +4,14 @@ namespace Ryujinx.HLE.HOS.Kernel
{
protected Horizon System;
public KAutoObject(Horizon System)
public KAutoObject(Horizon system)
{
this.System = System;
System = system;
}
public virtual KernelResult SetName(string Name)
public virtual KernelResult SetName(string name)
{
if (!System.AutoObjectNames.TryAdd(Name, this))
if (!System.AutoObjectNames.TryAdd(name, this))
{
return KernelResult.InvalidState;
}
@ -19,9 +19,9 @@ namespace Ryujinx.HLE.HOS.Kernel
return KernelResult.Success;
}
public static KernelResult RemoveName(Horizon System, string Name)
public static KernelResult RemoveName(Horizon system, string name)
{
if (!System.AutoObjectNames.TryRemove(Name, out _))
if (!system.AutoObjectNames.TryRemove(name, out _))
{
return KernelResult.NotFound;
}
@ -29,11 +29,11 @@ namespace Ryujinx.HLE.HOS.Kernel
return KernelResult.Success;
}
public static KAutoObject FindNamedObject(Horizon System, string Name)
public static KAutoObject FindNamedObject(Horizon system, string name)
{
if (System.AutoObjectNames.TryGetValue(Name, out KAutoObject Obj))
if (system.AutoObjectNames.TryGetValue(name, out KAutoObject obj))
{
return Obj;
return obj;
}
return null;

View file

@ -2,30 +2,30 @@ namespace Ryujinx.HLE.HOS.Kernel
{
class KClientPort : KSynchronizationObject
{
private int SessionsCount;
private int CurrentCapacity;
private int MaxSessions;
private int _sessionsCount;
private int _currentCapacity;
private int _maxSessions;
private KPort Parent;
private KPort _parent;
public KClientPort(Horizon System) : base(System) { }
public KClientPort(Horizon system) : base(system) { }
public void Initialize(KPort Parent, int MaxSessions)
public void Initialize(KPort parent, int maxSessions)
{
this.MaxSessions = MaxSessions;
this.Parent = Parent;
_maxSessions = maxSessions;
_parent = parent;
}
public new static KernelResult RemoveName(Horizon System, string Name)
public new static KernelResult RemoveName(Horizon system, string name)
{
KAutoObject FoundObj = KAutoObject.FindNamedObject(System, Name);
KAutoObject foundObj = FindNamedObject(system, name);
if (!(FoundObj is KClientPort))
if (!(foundObj is KClientPort))
{
return KernelResult.NotFound;
}
return KAutoObject.RemoveName(System, Name);
return KAutoObject.RemoveName(system, name);
}
}
}

View file

@ -5,67 +5,67 @@ namespace Ryujinx.HLE.HOS.Kernel
{
static class KConditionVariable
{
public static void Wait(Horizon System, LinkedList<KThread> ThreadList, object Mutex, long Timeout)
public static void Wait(Horizon system, LinkedList<KThread> threadList, object mutex, long timeout)
{
KThread CurrentThread = System.Scheduler.GetCurrentThread();
KThread currentThread = system.Scheduler.GetCurrentThread();
System.CriticalSection.Enter();
system.CriticalSection.Enter();
Monitor.Exit(Mutex);
Monitor.Exit(mutex);
CurrentThread.Withholder = ThreadList;
currentThread.Withholder = threadList;
CurrentThread.Reschedule(ThreadSchedState.Paused);
currentThread.Reschedule(ThreadSchedState.Paused);
CurrentThread.WithholderNode = ThreadList.AddLast(CurrentThread);
currentThread.WithholderNode = threadList.AddLast(currentThread);
if (CurrentThread.ShallBeTerminated ||
CurrentThread.SchedFlags == ThreadSchedState.TerminationPending)
if (currentThread.ShallBeTerminated ||
currentThread.SchedFlags == ThreadSchedState.TerminationPending)
{
ThreadList.Remove(CurrentThread.WithholderNode);
threadList.Remove(currentThread.WithholderNode);
CurrentThread.Reschedule(ThreadSchedState.Running);
currentThread.Reschedule(ThreadSchedState.Running);
CurrentThread.Withholder = null;
currentThread.Withholder = null;
System.CriticalSection.Leave();
system.CriticalSection.Leave();
}
else
{
if (Timeout > 0)
if (timeout > 0)
{
System.TimeManager.ScheduleFutureInvocation(CurrentThread, Timeout);
system.TimeManager.ScheduleFutureInvocation(currentThread, timeout);
}
System.CriticalSection.Leave();
system.CriticalSection.Leave();
if (Timeout > 0)
if (timeout > 0)
{
System.TimeManager.UnscheduleFutureInvocation(CurrentThread);
system.TimeManager.UnscheduleFutureInvocation(currentThread);
}
}
Monitor.Enter(Mutex);
Monitor.Enter(mutex);
}
public static void NotifyAll(Horizon System, LinkedList<KThread> ThreadList)
public static void NotifyAll(Horizon system, LinkedList<KThread> threadList)
{
System.CriticalSection.Enter();
system.CriticalSection.Enter();
LinkedListNode<KThread> Node = ThreadList.First;
LinkedListNode<KThread> node = threadList.First;
for (; Node != null; Node = ThreadList.First)
for (; node != null; node = threadList.First)
{
KThread Thread = Node.Value;
KThread thread = node.Value;
ThreadList.Remove(Thread.WithholderNode);
threadList.Remove(thread.WithholderNode);
Thread.Withholder = null;
thread.Withholder = null;
Thread.Reschedule(ThreadSchedState.Running);
thread.Reschedule(ThreadSchedState.Running);
}
System.CriticalSection.Leave();
system.CriticalSection.Leave();
}
}
}

View file

@ -7,77 +7,77 @@ namespace Ryujinx.HLE.HOS.Kernel
{
private const int IdMasksCount = 8;
private int[] IdMasks;
private int[] _idMasks;
private int NextFreeBitHint;
private int _nextFreeBitHint;
public KContextIdManager()
{
IdMasks = new int[IdMasksCount];
_idMasks = new int[IdMasksCount];
}
public int GetId()
{
lock (IdMasks)
lock (_idMasks)
{
int Id = 0;
int id = 0;
if (!TestBit(NextFreeBitHint))
if (!TestBit(_nextFreeBitHint))
{
Id = NextFreeBitHint;
id = _nextFreeBitHint;
}
else
{
for (int Index = 0; Index < IdMasksCount; Index++)
for (int index = 0; index < IdMasksCount; index++)
{
int Mask = IdMasks[Index];
int mask = _idMasks[index];
int FirstFreeBit = BitUtils.CountLeadingZeros32((Mask + 1) & ~Mask);
int firstFreeBit = BitUtils.CountLeadingZeros32((mask + 1) & ~mask);
if (FirstFreeBit < 32)
if (firstFreeBit < 32)
{
int BaseBit = Index * 32 + 31;
int baseBit = index * 32 + 31;
Id = BaseBit - FirstFreeBit;
id = baseBit - firstFreeBit;
break;
}
else if (Index == IdMasksCount - 1)
else if (index == IdMasksCount - 1)
{
throw new InvalidOperationException("Maximum number of Ids reached!");
}
}
}
NextFreeBitHint = Id + 1;
_nextFreeBitHint = id + 1;
SetBit(Id);
SetBit(id);
return Id;
return id;
}
}
public void PutId(int Id)
public void PutId(int id)
{
lock (IdMasks)
lock (_idMasks)
{
ClearBit(Id);
ClearBit(id);
}
}
private bool TestBit(int Bit)
private bool TestBit(int bit)
{
return (IdMasks[NextFreeBitHint / 32] & (1 << (NextFreeBitHint & 31))) != 0;
return (_idMasks[_nextFreeBitHint / 32] & (1 << (_nextFreeBitHint & 31))) != 0;
}
private void SetBit(int Bit)
private void SetBit(int bit)
{
IdMasks[NextFreeBitHint / 32] |= (1 << (NextFreeBitHint & 31));
_idMasks[_nextFreeBitHint / 32] |= (1 << (_nextFreeBitHint & 31));
}
private void ClearBit(int Bit)
private void ClearBit(int bit)
{
IdMasks[NextFreeBitHint / 32] &= ~(1 << (NextFreeBitHint & 31));
_idMasks[_nextFreeBitHint / 32] &= ~(1 << (_nextFreeBitHint & 31));
}
}
}

View file

@ -4,9 +4,9 @@ namespace Ryujinx.HLE.HOS.Kernel
{
class KCoreContext
{
private KScheduler Scheduler;
private KScheduler _scheduler;
private HleCoreManager CoreManager;
private HleCoreManager _coreManager;
public bool ContextSwitchNeeded { get; private set; }
@ -17,15 +17,15 @@ namespace Ryujinx.HLE.HOS.Kernel
public KThread CurrentThread { get; private set; }
public KThread SelectedThread { get; private set; }
public KCoreContext(KScheduler Scheduler, HleCoreManager CoreManager)
public KCoreContext(KScheduler scheduler, HleCoreManager coreManager)
{
this.Scheduler = Scheduler;
this.CoreManager = CoreManager;
_scheduler = scheduler;
_coreManager = coreManager;
}
public void SelectThread(KThread Thread)
public void SelectThread(KThread thread)
{
SelectedThread = Thread;
SelectedThread = thread;
if (SelectedThread != CurrentThread)
{
@ -43,10 +43,10 @@ namespace Ryujinx.HLE.HOS.Kernel
if (CurrentThread != null)
{
long CurrentTime = PerformanceCounter.ElapsedMilliseconds;
long currentTime = PerformanceCounter.ElapsedMilliseconds;
CurrentThread.TotalTimeRunning += CurrentTime - CurrentThread.LastScheduledTime;
CurrentThread.LastScheduledTime = CurrentTime;
CurrentThread.TotalTimeRunning += currentTime - CurrentThread.LastScheduledTime;
CurrentThread.LastScheduledTime = currentTime;
}
}
@ -58,21 +58,21 @@ namespace Ryujinx.HLE.HOS.Kernel
if (CurrentThread != null)
{
CoreManager.Reset(CurrentThread.Context.Work);
_coreManager.Reset(CurrentThread.Context.Work);
}
CurrentThread = SelectedThread;
if (CurrentThread != null)
{
long CurrentTime = PerformanceCounter.ElapsedMilliseconds;
long currentTime = PerformanceCounter.ElapsedMilliseconds;
CurrentThread.TotalTimeRunning += CurrentTime - CurrentThread.LastScheduledTime;
CurrentThread.LastScheduledTime = CurrentTime;
CurrentThread.TotalTimeRunning += currentTime - CurrentThread.LastScheduledTime;
CurrentThread.LastScheduledTime = currentTime;
CurrentThread.ClearExclusive();
CoreManager.Set(CurrentThread.Context.Work);
_coreManager.Set(CurrentThread.Context.Work);
CurrentThread.Context.Execute();
}

View file

@ -5,15 +5,15 @@ namespace Ryujinx.HLE.HOS.Kernel
{
class KCriticalSection
{
private Horizon System;
private Horizon _system;
public object LockObj { get; private set; }
public object LockObj { get; }
private int RecursionCount;
private int _recursionCount;
public KCriticalSection(Horizon System)
public KCriticalSection(Horizon system)
{
this.System = System;
_system = system;
LockObj = new object();
}
@ -22,53 +22,53 @@ namespace Ryujinx.HLE.HOS.Kernel
{
Monitor.Enter(LockObj);
RecursionCount++;
_recursionCount++;
}
public void Leave()
{
if (RecursionCount == 0)
if (_recursionCount == 0)
{
return;
}
bool DoContextSwitch = false;
bool doContextSwitch = false;
if (--RecursionCount == 0)
if (--_recursionCount == 0)
{
if (System.Scheduler.ThreadReselectionRequested)
if (_system.Scheduler.ThreadReselectionRequested)
{
System.Scheduler.SelectThreads();
_system.Scheduler.SelectThreads();
}
Monitor.Exit(LockObj);
if (System.Scheduler.MultiCoreScheduling)
if (_system.Scheduler.MultiCoreScheduling)
{
lock (System.Scheduler.CoreContexts)
lock (_system.Scheduler.CoreContexts)
{
for (int Core = 0; Core < KScheduler.CpuCoresCount; Core++)
for (int core = 0; core < KScheduler.CpuCoresCount; core++)
{
KCoreContext CoreContext = System.Scheduler.CoreContexts[Core];
KCoreContext coreContext = _system.Scheduler.CoreContexts[core];
if (CoreContext.ContextSwitchNeeded)
if (coreContext.ContextSwitchNeeded)
{
CpuThread CurrentHleThread = CoreContext.CurrentThread?.Context;
CpuThread currentHleThread = coreContext.CurrentThread?.Context;
if (CurrentHleThread == null)
if (currentHleThread == null)
{
//Nothing is running, we can perform the context switch immediately.
CoreContext.ContextSwitch();
coreContext.ContextSwitch();
}
else if (CurrentHleThread.IsCurrentThread())
else if (currentHleThread.IsCurrentThread())
{
//Thread running on the current core, context switch will block.
DoContextSwitch = true;
doContextSwitch = true;
}
else
{
//Thread running on another core, request a interrupt.
CurrentHleThread.RequestInterrupt();
currentHleThread.RequestInterrupt();
}
}
}
@ -76,7 +76,7 @@ namespace Ryujinx.HLE.HOS.Kernel
}
else
{
DoContextSwitch = true;
doContextSwitch = true;
}
}
else
@ -84,9 +84,9 @@ namespace Ryujinx.HLE.HOS.Kernel
Monitor.Exit(LockObj);
}
if (DoContextSwitch)
if (doContextSwitch)
{
System.Scheduler.ContextSwitch();
_system.Scheduler.ContextSwitch();
}
}
}

View file

@ -2,12 +2,12 @@ namespace Ryujinx.HLE.HOS.Kernel
{
class KEvent
{
public KReadableEvent ReadableEvent { get; private set; }
public KWritableEvent WritableEvent { get; private set; }
public KReadableEvent ReadableEvent { get; }
public KWritableEvent WritableEvent { get; }
public KEvent(Horizon System)
public KEvent(Horizon system)
{
ReadableEvent = new KReadableEvent(System, this);
ReadableEvent = new KReadableEvent(system, this);
WritableEvent = new KWritableEvent(this);
}
}

View file

@ -4,14 +4,14 @@ namespace Ryujinx.HLE.HOS.Kernel
{
public KHandleEntry Next { get; set; }
public int Index { get; private set; }
public int Index { get; }
public ushort HandleId { get; set; }
public object Obj { get; set; }
public KHandleEntry(int Index)
public KHandleEntry(int index)
{
this.Index = Index;
Index = index;
}
}
}

View file

@ -7,148 +7,148 @@ namespace Ryujinx.HLE.HOS.Kernel
private const int SelfThreadHandle = (0x1ffff << 15) | 0;
private const int SelfProcessHandle = (0x1ffff << 15) | 1;
private Horizon System;
private Horizon _system;
private KHandleEntry[] Table;
private KHandleEntry[] _table;
private KHandleEntry TableHead;
private KHandleEntry NextFreeEntry;
private KHandleEntry _tableHead;
private KHandleEntry _nextFreeEntry;
private int ActiveSlotsCount;
private int _activeSlotsCount;
private int Size;
private int _size;
private ushort IdCounter;
private ushort _idCounter;
public KHandleTable(Horizon System)
public KHandleTable(Horizon system)
{
this.System = System;
_system = system;
}
public KernelResult Initialize(int Size)
public KernelResult Initialize(int size)
{
if ((uint)Size > 1024)
if ((uint)size > 1024)
{
return KernelResult.OutOfMemory;
}
if (Size < 1)
if (size < 1)
{
Size = 1024;
size = 1024;
}
this.Size = Size;
_size = size;
IdCounter = 1;
_idCounter = 1;
Table = new KHandleEntry[Size];
_table = new KHandleEntry[size];
TableHead = new KHandleEntry(0);
_tableHead = new KHandleEntry(0);
KHandleEntry Entry = TableHead;
KHandleEntry entry = _tableHead;
for (int Index = 0; Index < Size; Index++)
for (int index = 0; index < size; index++)
{
Table[Index] = Entry;
_table[index] = entry;
Entry.Next = new KHandleEntry(Index + 1);
entry.Next = new KHandleEntry(index + 1);
Entry = Entry.Next;
entry = entry.Next;
}
Table[Size - 1].Next = null;
_table[size - 1].Next = null;
NextFreeEntry = TableHead;
_nextFreeEntry = _tableHead;
return KernelResult.Success;
}
public KernelResult GenerateHandle(object Obj, out int Handle)
public KernelResult GenerateHandle(object obj, out int handle)
{
Handle = 0;
handle = 0;
lock (Table)
lock (_table)
{
if (ActiveSlotsCount >= Size)
if (_activeSlotsCount >= _size)
{
return KernelResult.HandleTableFull;
}
KHandleEntry Entry = NextFreeEntry;
KHandleEntry entry = _nextFreeEntry;
NextFreeEntry = Entry.Next;
_nextFreeEntry = entry.Next;
Entry.Obj = Obj;
Entry.HandleId = IdCounter;
entry.Obj = obj;
entry.HandleId = _idCounter;
ActiveSlotsCount++;
_activeSlotsCount++;
Handle = (int)((IdCounter << 15) & (uint)0xffff8000) | Entry.Index;
handle = (int)((_idCounter << 15) & 0xffff8000) | entry.Index;
if ((short)(IdCounter + 1) >= 0)
if ((short)(_idCounter + 1) >= 0)
{
IdCounter++;
_idCounter++;
}
else
{
IdCounter = 1;
_idCounter = 1;
}
}
return KernelResult.Success;
}
public bool CloseHandle(int Handle)
public bool CloseHandle(int handle)
{
if ((Handle >> 30) != 0 ||
Handle == SelfThreadHandle ||
Handle == SelfProcessHandle)
if ((handle >> 30) != 0 ||
handle == SelfThreadHandle ||
handle == SelfProcessHandle)
{
return false;
}
int Index = (Handle >> 0) & 0x7fff;
int HandleId = (Handle >> 15);
int index = (handle >> 0) & 0x7fff;
int handleId = (handle >> 15);
bool Result = false;
bool result = false;
lock (Table)
lock (_table)
{
if (HandleId != 0 && Index < Size)
if (handleId != 0 && index < _size)
{
KHandleEntry Entry = Table[Index];
KHandleEntry entry = _table[index];
if (Entry.Obj != null && Entry.HandleId == HandleId)
if (entry.Obj != null && entry.HandleId == handleId)
{
Entry.Obj = null;
Entry.Next = NextFreeEntry;
entry.Obj = null;
entry.Next = _nextFreeEntry;
NextFreeEntry = Entry;
_nextFreeEntry = entry;
ActiveSlotsCount--;
_activeSlotsCount--;
Result = true;
result = true;
}
}
}
return Result;
return result;
}
public T GetObject<T>(int Handle)
public T GetObject<T>(int handle)
{
int Index = (Handle >> 0) & 0x7fff;
int HandleId = (Handle >> 15);
int index = (handle >> 0) & 0x7fff;
int handleId = (handle >> 15);
lock (Table)
lock (_table)
{
if ((Handle >> 30) == 0 && HandleId != 0)
if ((handle >> 30) == 0 && handleId != 0)
{
KHandleEntry Entry = Table[Index];
KHandleEntry entry = _table[index];
if (Entry.HandleId == HandleId && Entry.Obj is T Obj)
if (entry.HandleId == handleId && entry.Obj is T obj)
{
return Obj;
return obj;
}
}
}
@ -156,49 +156,49 @@ namespace Ryujinx.HLE.HOS.Kernel
return default(T);
}
public KThread GetKThread(int Handle)
public KThread GetKThread(int handle)
{
if (Handle == SelfThreadHandle)
if (handle == SelfThreadHandle)
{
return System.Scheduler.GetCurrentThread();
return _system.Scheduler.GetCurrentThread();
}
else
{
return GetObject<KThread>(Handle);
return GetObject<KThread>(handle);
}
}
public KProcess GetKProcess(int Handle)
public KProcess GetKProcess(int handle)
{
if (Handle == SelfProcessHandle)
if (handle == SelfProcessHandle)
{
return System.Scheduler.GetCurrentProcess();
return _system.Scheduler.GetCurrentProcess();
}
else
{
return GetObject<KProcess>(Handle);
return GetObject<KProcess>(handle);
}
}
public void Destroy()
{
lock (Table)
lock (_table)
{
for (int Index = 0; Index < Size; Index++)
for (int index = 0; index < _size; index++)
{
KHandleEntry Entry = Table[Index];
KHandleEntry entry = _table[index];
if (Entry.Obj != null)
if (entry.Obj != null)
{
if (Entry.Obj is IDisposable DisposableObj)
if (entry.Obj is IDisposable disposableObj)
{
DisposableObj.Dispose();
disposableObj.Dispose();
}
Entry.Obj = null;
Entry.Next = NextFreeEntry;
entry.Obj = null;
entry.Next = _nextFreeEntry;
NextFreeEntry = Entry;
_nextFreeEntry = entry;
}
}
}

View file

@ -2,21 +2,21 @@ namespace Ryujinx.HLE.HOS.Kernel
{
class KMemoryArrange
{
public KMemoryArrangeRegion Service { get; private set; }
public KMemoryArrangeRegion NvServices { get; private set; }
public KMemoryArrangeRegion Applet { get; private set; }
public KMemoryArrangeRegion Application { get; private set; }
public KMemoryArrangeRegion Service { get; }
public KMemoryArrangeRegion NvServices { get; }
public KMemoryArrangeRegion Applet { get; }
public KMemoryArrangeRegion Application { get; }
public KMemoryArrange(
KMemoryArrangeRegion Service,
KMemoryArrangeRegion NvServices,
KMemoryArrangeRegion Applet,
KMemoryArrangeRegion Application)
KMemoryArrangeRegion service,
KMemoryArrangeRegion nvServices,
KMemoryArrangeRegion applet,
KMemoryArrangeRegion application)
{
this.Service = Service;
this.NvServices = NvServices;
this.Applet = Applet;
this.Application = Application;
Service = service;
NvServices = nvServices;
Applet = applet;
Application = application;
}
}
}

View file

@ -2,15 +2,15 @@ namespace Ryujinx.HLE.HOS.Kernel
{
struct KMemoryArrangeRegion
{
public ulong Address { get; private set; }
public ulong Size { get; private set; }
public ulong Address { get; }
public ulong Size { get; }
public ulong EndAddr => Address + Size;
public KMemoryArrangeRegion(ulong Address, ulong Size)
public KMemoryArrangeRegion(ulong address, ulong size)
{
this.Address = Address;
this.Size = Size;
Address = address;
Size = size;
}
}
}

View file

@ -13,26 +13,26 @@ namespace Ryujinx.HLE.HOS.Kernel
public int DeviceRefCount { get; set; }
public KMemoryBlock(
ulong BaseAddress,
ulong PagesCount,
MemoryState State,
MemoryPermission Permission,
MemoryAttribute Attribute)
ulong baseAddress,
ulong pagesCount,
MemoryState state,
MemoryPermission permission,
MemoryAttribute attribute)
{
this.BaseAddress = BaseAddress;
this.PagesCount = PagesCount;
this.State = State;
this.Attribute = Attribute;
this.Permission = Permission;
BaseAddress = baseAddress;
PagesCount = pagesCount;
State = state;
Attribute = attribute;
Permission = permission;
}
public KMemoryInfo GetInfo()
{
ulong Size = PagesCount * KMemoryManager.PageSize;
ulong size = PagesCount * KMemoryManager.PageSize;
return new KMemoryInfo(
BaseAddress,
Size,
size,
State,
Permission,
Attribute,

View file

@ -2,18 +2,18 @@ namespace Ryujinx.HLE.HOS.Kernel
{
class KMemoryBlockAllocator
{
private ulong CapacityElements;
private ulong _capacityElements;
public int Count { get; set; }
public KMemoryBlockAllocator(ulong CapacityElements)
public KMemoryBlockAllocator(ulong capacityElements)
{
this.CapacityElements = CapacityElements;
_capacityElements = capacityElements;
}
public bool CanAllocate(int Count)
public bool CanAllocate(int count)
{
return (ulong)(this.Count + Count) <= CapacityElements;
return (ulong)(Count + count) <= _capacityElements;
}
}
}

View file

@ -2,32 +2,32 @@ namespace Ryujinx.HLE.HOS.Kernel
{
class KMemoryInfo
{
public ulong Address { get; private set; }
public ulong Size { get; private set; }
public ulong Address { get; }
public ulong Size { get; }
public MemoryState State { get; private set; }
public MemoryPermission Permission { get; private set; }
public MemoryAttribute Attribute { get; private set; }
public MemoryState State { get; }
public MemoryPermission Permission { get; }
public MemoryAttribute Attribute { get; }
public int IpcRefCount { get; private set; }
public int DeviceRefCount { get; private set; }
public int IpcRefCount { get; }
public int DeviceRefCount { get; }
public KMemoryInfo(
ulong Address,
ulong Size,
MemoryState State,
MemoryPermission Permission,
MemoryAttribute Attribute,
int IpcRefCount,
int DeviceRefCount)
ulong address,
ulong size,
MemoryState state,
MemoryPermission permission,
MemoryAttribute attribute,
int ipcRefCount,
int deviceRefCount)
{
this.Address = Address;
this.Size = Size;
this.State = State;
this.Attribute = Attribute;
this.Permission = Permission;
this.IpcRefCount = IpcRefCount;
this.DeviceRefCount = DeviceRefCount;
Address = address;
Size = size;
State = state;
Attribute = attribute;
Permission = permission;
IpcRefCount = ipcRefCount;
DeviceRefCount = deviceRefCount;
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -12,30 +12,30 @@ namespace Ryujinx.HLE.HOS.Kernel
public int Order;
public int NextOrder;
public bool TryCoalesce(int Index, int Size)
public bool TryCoalesce(int index, int size)
{
long Mask = ((1L << Size) - 1) << (Index & 63);
long mask = ((1L << size) - 1) << (index & 63);
Index /= 64;
index /= 64;
if ((Mask & ~Masks[MaxLevel - 1][Index]) != 0)
if ((mask & ~Masks[MaxLevel - 1][index]) != 0)
{
return false;
}
Masks[MaxLevel - 1][Index] &= ~Mask;
Masks[MaxLevel - 1][index] &= ~mask;
for (int Level = MaxLevel - 2; Level >= 0; Level--, Index /= 64)
for (int level = MaxLevel - 2; level >= 0; level--, index /= 64)
{
Masks[Level][Index / 64] &= ~(1L << (Index & 63));
Masks[level][index / 64] &= ~(1L << (index & 63));
if (Masks[Level][Index / 64] != 0)
if (Masks[level][index / 64] != 0)
{
break;
}
}
FreeCount -= (ulong)Size;
FreeCount -= (ulong)size;
return true;
}

View file

@ -6,404 +6,404 @@ namespace Ryujinx.HLE.HOS.Kernel
{
private static readonly int[] BlockOrders = new int[] { 12, 16, 21, 22, 25, 29, 30 };
public ulong Address { get; private set; }
public ulong EndAddr { get; private set; }
public ulong Size { get; private set; }
public ulong Address { get; }
public ulong EndAddr { get; }
public ulong Size { get; }
private int BlockOrdersCount;
private int _blockOrdersCount;
private KMemoryRegionBlock[] Blocks;
private KMemoryRegionBlock[] _blocks;
public KMemoryRegionManager(ulong Address, ulong Size, ulong EndAddr)
public KMemoryRegionManager(ulong address, ulong size, ulong endAddr)
{
Blocks = new KMemoryRegionBlock[BlockOrders.Length];
_blocks = new KMemoryRegionBlock[BlockOrders.Length];
this.Address = Address;
this.Size = Size;
this.EndAddr = EndAddr;
Address = address;
Size = size;
EndAddr = endAddr;
BlockOrdersCount = BlockOrders.Length;
_blockOrdersCount = BlockOrders.Length;
for (int BlockIndex = 0; BlockIndex < BlockOrdersCount; BlockIndex++)
for (int blockIndex = 0; blockIndex < _blockOrdersCount; blockIndex++)
{
Blocks[BlockIndex] = new KMemoryRegionBlock();
_blocks[blockIndex] = new KMemoryRegionBlock();
Blocks[BlockIndex].Order = BlockOrders[BlockIndex];
_blocks[blockIndex].Order = BlockOrders[blockIndex];
int NextOrder = BlockIndex == BlockOrdersCount - 1 ? 0 : BlockOrders[BlockIndex + 1];
int nextOrder = blockIndex == _blockOrdersCount - 1 ? 0 : BlockOrders[blockIndex + 1];
Blocks[BlockIndex].NextOrder = NextOrder;
_blocks[blockIndex].NextOrder = nextOrder;
int CurrBlockSize = 1 << BlockOrders[BlockIndex];
int NextBlockSize = CurrBlockSize;
int currBlockSize = 1 << BlockOrders[blockIndex];
int nextBlockSize = currBlockSize;
if (NextOrder != 0)
if (nextOrder != 0)
{
NextBlockSize = 1 << NextOrder;
nextBlockSize = 1 << nextOrder;
}
ulong StartAligned = BitUtils.AlignDown(Address, NextBlockSize);
ulong EndAddrAligned = BitUtils.AlignDown(EndAddr, CurrBlockSize);
ulong startAligned = BitUtils.AlignDown(address, nextBlockSize);
ulong endAddrAligned = BitUtils.AlignDown(endAddr, currBlockSize);
ulong SizeInBlocksTruncated = (EndAddrAligned - StartAligned) >> BlockOrders[BlockIndex];
ulong sizeInBlocksTruncated = (endAddrAligned - startAligned) >> BlockOrders[blockIndex];
ulong EndAddrRounded = BitUtils.AlignUp(Address + Size, NextBlockSize);
ulong endAddrRounded = BitUtils.AlignUp(address + size, nextBlockSize);
ulong SizeInBlocksRounded = (EndAddrRounded - StartAligned) >> BlockOrders[BlockIndex];
ulong sizeInBlocksRounded = (endAddrRounded - startAligned) >> BlockOrders[blockIndex];
Blocks[BlockIndex].StartAligned = StartAligned;
Blocks[BlockIndex].SizeInBlocksTruncated = SizeInBlocksTruncated;
Blocks[BlockIndex].SizeInBlocksRounded = SizeInBlocksRounded;
_blocks[blockIndex].StartAligned = startAligned;
_blocks[blockIndex].SizeInBlocksTruncated = sizeInBlocksTruncated;
_blocks[blockIndex].SizeInBlocksRounded = sizeInBlocksRounded;
ulong CurrSizeInBlocks = SizeInBlocksRounded;
ulong currSizeInBlocks = sizeInBlocksRounded;
int MaxLevel = 0;
int maxLevel = 0;
do
{
MaxLevel++;
maxLevel++;
}
while ((CurrSizeInBlocks /= 64) != 0);
while ((currSizeInBlocks /= 64) != 0);
Blocks[BlockIndex].MaxLevel = MaxLevel;
_blocks[blockIndex].MaxLevel = maxLevel;
Blocks[BlockIndex].Masks = new long[MaxLevel][];
_blocks[blockIndex].Masks = new long[maxLevel][];
CurrSizeInBlocks = SizeInBlocksRounded;
currSizeInBlocks = sizeInBlocksRounded;
for (int Level = MaxLevel - 1; Level >= 0; Level--)
for (int level = maxLevel - 1; level >= 0; level--)
{
CurrSizeInBlocks = (CurrSizeInBlocks + 63) / 64;
currSizeInBlocks = (currSizeInBlocks + 63) / 64;
Blocks[BlockIndex].Masks[Level] = new long[CurrSizeInBlocks];
_blocks[blockIndex].Masks[level] = new long[currSizeInBlocks];
}
}
if (Size != 0)
if (size != 0)
{
FreePages(Address, Size / KMemoryManager.PageSize);
FreePages(address, size / KMemoryManager.PageSize);
}
}
public KernelResult AllocatePages(ulong PagesCount, bool Backwards, out KPageList PageList)
public KernelResult AllocatePages(ulong pagesCount, bool backwards, out KPageList pageList)
{
lock (Blocks)
lock (_blocks)
{
return AllocatePagesImpl(PagesCount, Backwards, out PageList);
return AllocatePagesImpl(pagesCount, backwards, out pageList);
}
}
private KernelResult AllocatePagesImpl(ulong PagesCount, bool Backwards, out KPageList PageList)
private KernelResult AllocatePagesImpl(ulong pagesCount, bool backwards, out KPageList pageList)
{
PageList = new KPageList();
pageList = new KPageList();
if (BlockOrdersCount > 0)
if (_blockOrdersCount > 0)
{
if (GetFreePagesImpl() < PagesCount)
if (GetFreePagesImpl() < pagesCount)
{
return KernelResult.OutOfMemory;
}
}
else if (PagesCount != 0)
else if (pagesCount != 0)
{
return KernelResult.OutOfMemory;
}
for (int BlockIndex = BlockOrdersCount - 1; BlockIndex >= 0; BlockIndex--)
for (int blockIndex = _blockOrdersCount - 1; blockIndex >= 0; blockIndex--)
{
KMemoryRegionBlock Block = Blocks[BlockIndex];
KMemoryRegionBlock block = _blocks[blockIndex];
ulong BestFitBlockSize = 1UL << Block.Order;
ulong bestFitBlockSize = 1UL << block.Order;
ulong BlockPagesCount = BestFitBlockSize / KMemoryManager.PageSize;
ulong blockPagesCount = bestFitBlockSize / KMemoryManager.PageSize;
//Check if this is the best fit for this page size.
//If so, try allocating as much requested pages as possible.
while (BlockPagesCount <= PagesCount)
while (blockPagesCount <= pagesCount)
{
ulong Address = 0;
ulong address = 0;
for (int CurrBlockIndex = BlockIndex;
CurrBlockIndex < BlockOrdersCount && Address == 0;
CurrBlockIndex++)
for (int currBlockIndex = blockIndex;
currBlockIndex < _blockOrdersCount && address == 0;
currBlockIndex++)
{
Block = Blocks[CurrBlockIndex];
block = _blocks[currBlockIndex];
int Index = 0;
int index = 0;
bool ZeroMask = false;
bool zeroMask = false;
for (int Level = 0; Level < Block.MaxLevel; Level++)
for (int level = 0; level < block.MaxLevel; level++)
{
long Mask = Block.Masks[Level][Index];
long mask = block.Masks[level][index];
if (Mask == 0)
if (mask == 0)
{
ZeroMask = true;
zeroMask = true;
break;
}
if (Backwards)
if (backwards)
{
Index = (Index * 64 + 63) - BitUtils.CountLeadingZeros64(Mask);
index = (index * 64 + 63) - BitUtils.CountLeadingZeros64(mask);
}
else
{
Index = Index * 64 + BitUtils.CountLeadingZeros64(BitUtils.ReverseBits64(Mask));
index = index * 64 + BitUtils.CountLeadingZeros64(BitUtils.ReverseBits64(mask));
}
}
if (Block.SizeInBlocksTruncated <= (ulong)Index || ZeroMask)
if (block.SizeInBlocksTruncated <= (ulong)index || zeroMask)
{
continue;
}
Block.FreeCount--;
block.FreeCount--;
int TempIdx = Index;
int tempIdx = index;
for (int Level = Block.MaxLevel - 1; Level >= 0; Level--, TempIdx /= 64)
for (int level = block.MaxLevel - 1; level >= 0; level--, tempIdx /= 64)
{
Block.Masks[Level][TempIdx / 64] &= ~(1L << (TempIdx & 63));
block.Masks[level][tempIdx / 64] &= ~(1L << (tempIdx & 63));
if (Block.Masks[Level][TempIdx / 64] != 0)
if (block.Masks[level][tempIdx / 64] != 0)
{
break;
}
}
Address = Block.StartAligned + ((ulong)Index << Block.Order);
address = block.StartAligned + ((ulong)index << block.Order);
}
for (int CurrBlockIndex = BlockIndex;
CurrBlockIndex < BlockOrdersCount && Address == 0;
CurrBlockIndex++)
for (int currBlockIndex = blockIndex;
currBlockIndex < _blockOrdersCount && address == 0;
currBlockIndex++)
{
Block = Blocks[CurrBlockIndex];
block = _blocks[currBlockIndex];
int Index = 0;
int index = 0;
bool ZeroMask = false;
bool zeroMask = false;
for (int Level = 0; Level < Block.MaxLevel; Level++)
for (int level = 0; level < block.MaxLevel; level++)
{
long Mask = Block.Masks[Level][Index];
long mask = block.Masks[level][index];
if (Mask == 0)
if (mask == 0)
{
ZeroMask = true;
zeroMask = true;
break;
}
if (Backwards)
if (backwards)
{
Index = Index * 64 + BitUtils.CountLeadingZeros64(BitUtils.ReverseBits64(Mask));
index = index * 64 + BitUtils.CountLeadingZeros64(BitUtils.ReverseBits64(mask));
}
else
{
Index = (Index * 64 + 63) - BitUtils.CountLeadingZeros64(Mask);
index = (index * 64 + 63) - BitUtils.CountLeadingZeros64(mask);
}
}
if (Block.SizeInBlocksTruncated <= (ulong)Index || ZeroMask)
if (block.SizeInBlocksTruncated <= (ulong)index || zeroMask)
{
continue;
}
Block.FreeCount--;
block.FreeCount--;
int TempIdx = Index;
int tempIdx = index;
for (int Level = Block.MaxLevel - 1; Level >= 0; Level--, TempIdx /= 64)
for (int level = block.MaxLevel - 1; level >= 0; level--, tempIdx /= 64)
{
Block.Masks[Level][TempIdx / 64] &= ~(1L << (TempIdx & 63));
block.Masks[level][tempIdx / 64] &= ~(1L << (tempIdx & 63));
if (Block.Masks[Level][TempIdx / 64] != 0)
if (block.Masks[level][tempIdx / 64] != 0)
{
break;
}
}
Address = Block.StartAligned + ((ulong)Index << Block.Order);
address = block.StartAligned + ((ulong)index << block.Order);
}
//The address being zero means that no free space was found on that order,
//just give up and try with the next one.
if (Address == 0)
if (address == 0)
{
break;
}
//If we are using a larger order than best fit, then we should
//split it into smaller blocks.
ulong FirstFreeBlockSize = 1UL << Block.Order;
ulong firstFreeBlockSize = 1UL << block.Order;
if (FirstFreeBlockSize > BestFitBlockSize)
if (firstFreeBlockSize > bestFitBlockSize)
{
FreePages(Address + BestFitBlockSize, (FirstFreeBlockSize - BestFitBlockSize) / KMemoryManager.PageSize);
FreePages(address + bestFitBlockSize, (firstFreeBlockSize - bestFitBlockSize) / KMemoryManager.PageSize);
}
//Add new allocated page(s) to the pages list.
//If an error occurs, then free all allocated pages and fail.
KernelResult Result = PageList.AddRange(Address, BlockPagesCount);
KernelResult result = pageList.AddRange(address, blockPagesCount);
if (Result != KernelResult.Success)
if (result != KernelResult.Success)
{
FreePages(Address, BlockPagesCount);
FreePages(address, blockPagesCount);
foreach (KPageNode PageNode in PageList)
foreach (KPageNode pageNode in pageList)
{
FreePages(PageNode.Address, PageNode.PagesCount);
FreePages(pageNode.Address, pageNode.PagesCount);
}
return Result;
return result;
}
PagesCount -= BlockPagesCount;
pagesCount -= blockPagesCount;
}
}
//Success case, all requested pages were allocated successfully.
if (PagesCount == 0)
if (pagesCount == 0)
{
return KernelResult.Success;
}
//Error case, free allocated pages and return out of memory.
foreach (KPageNode PageNode in PageList)
foreach (KPageNode pageNode in pageList)
{
FreePages(PageNode.Address, PageNode.PagesCount);
FreePages(pageNode.Address, pageNode.PagesCount);
}
PageList = null;
pageList = null;
return KernelResult.OutOfMemory;
}
public void FreePages(KPageList PageList)
public void FreePages(KPageList pageList)
{
lock (Blocks)
lock (_blocks)
{
foreach (KPageNode PageNode in PageList)
foreach (KPageNode pageNode in pageList)
{
FreePages(PageNode.Address, PageNode.PagesCount);
FreePages(pageNode.Address, pageNode.PagesCount);
}
}
}
private void FreePages(ulong Address, ulong PagesCount)
private void FreePages(ulong address, ulong pagesCount)
{
ulong EndAddr = Address + PagesCount * KMemoryManager.PageSize;
ulong endAddr = address + pagesCount * KMemoryManager.PageSize;
int BlockIndex = BlockOrdersCount - 1;
int blockIndex = _blockOrdersCount - 1;
ulong AddressRounded = 0;
ulong EndAddrTruncated = 0;
ulong addressRounded = 0;
ulong endAddrTruncated = 0;
for (; BlockIndex >= 0; BlockIndex--)
for (; blockIndex >= 0; blockIndex--)
{
KMemoryRegionBlock AllocInfo = Blocks[BlockIndex];
KMemoryRegionBlock allocInfo = _blocks[blockIndex];
int BlockSize = 1 << AllocInfo.Order;
int blockSize = 1 << allocInfo.Order;
AddressRounded = BitUtils.AlignUp (Address, BlockSize);
EndAddrTruncated = BitUtils.AlignDown(EndAddr, BlockSize);
addressRounded = BitUtils.AlignUp (address, blockSize);
endAddrTruncated = BitUtils.AlignDown(endAddr, blockSize);
if (AddressRounded < EndAddrTruncated)
if (addressRounded < endAddrTruncated)
{
break;
}
}
void FreeRegion(ulong CurrAddress)
void FreeRegion(ulong currAddress)
{
for (int CurrBlockIndex = BlockIndex;
CurrBlockIndex < BlockOrdersCount && CurrAddress != 0;
CurrBlockIndex++)
for (int currBlockIndex = blockIndex;
currBlockIndex < _blockOrdersCount && currAddress != 0;
currBlockIndex++)
{
KMemoryRegionBlock Block = Blocks[CurrBlockIndex];
KMemoryRegionBlock block = _blocks[currBlockIndex];
Block.FreeCount++;
block.FreeCount++;
ulong FreedBlocks = (CurrAddress - Block.StartAligned) >> Block.Order;
ulong freedBlocks = (currAddress - block.StartAligned) >> block.Order;
int Index = (int)FreedBlocks;
int index = (int)freedBlocks;
for (int Level = Block.MaxLevel - 1; Level >= 0; Level--, Index /= 64)
for (int level = block.MaxLevel - 1; level >= 0; level--, index /= 64)
{
long Mask = Block.Masks[Level][Index / 64];
long mask = block.Masks[level][index / 64];
Block.Masks[Level][Index / 64] = Mask | (1L << (Index & 63));
block.Masks[level][index / 64] = mask | (1L << (index & 63));
if (Mask != 0)
if (mask != 0)
{
break;
}
}
int BlockSizeDelta = 1 << (Block.NextOrder - Block.Order);
int blockSizeDelta = 1 << (block.NextOrder - block.Order);
int FreedBlocksTruncated = BitUtils.AlignDown((int)FreedBlocks, BlockSizeDelta);
int freedBlocksTruncated = BitUtils.AlignDown((int)freedBlocks, blockSizeDelta);
if (!Block.TryCoalesce(FreedBlocksTruncated, BlockSizeDelta))
if (!block.TryCoalesce(freedBlocksTruncated, blockSizeDelta))
{
break;
}
CurrAddress = Block.StartAligned + ((ulong)FreedBlocksTruncated << Block.Order);
currAddress = block.StartAligned + ((ulong)freedBlocksTruncated << block.Order);
}
}
//Free inside aligned region.
ulong BaseAddress = AddressRounded;
ulong baseAddress = addressRounded;
while (BaseAddress < EndAddrTruncated)
while (baseAddress < endAddrTruncated)
{
ulong BlockSize = 1UL << Blocks[BlockIndex].Order;
ulong blockSize = 1UL << _blocks[blockIndex].Order;
FreeRegion(BaseAddress);
FreeRegion(baseAddress);
BaseAddress += BlockSize;
baseAddress += blockSize;
}
int NextBlockIndex = BlockIndex - 1;
int nextBlockIndex = blockIndex - 1;
//Free region between Address and aligned region start.
BaseAddress = AddressRounded;
baseAddress = addressRounded;
for (BlockIndex = NextBlockIndex; BlockIndex >= 0; BlockIndex--)
for (blockIndex = nextBlockIndex; blockIndex >= 0; blockIndex--)
{
ulong BlockSize = 1UL << Blocks[BlockIndex].Order;
ulong blockSize = 1UL << _blocks[blockIndex].Order;
while (BaseAddress - BlockSize >= Address)
while (baseAddress - blockSize >= address)
{
BaseAddress -= BlockSize;
baseAddress -= blockSize;
FreeRegion(BaseAddress);
FreeRegion(baseAddress);
}
}
//Free region between aligned region end and End Address.
BaseAddress = EndAddrTruncated;
baseAddress = endAddrTruncated;
for (BlockIndex = NextBlockIndex; BlockIndex >= 0; BlockIndex--)
for (blockIndex = nextBlockIndex; blockIndex >= 0; blockIndex--)
{
ulong BlockSize = 1UL << Blocks[BlockIndex].Order;
ulong blockSize = 1UL << _blocks[blockIndex].Order;
while (BaseAddress + BlockSize <= EndAddr)
while (baseAddress + blockSize <= endAddr)
{
FreeRegion(BaseAddress);
FreeRegion(baseAddress);
BaseAddress += BlockSize;
baseAddress += blockSize;
}
}
}
public ulong GetFreePages()
{
lock (Blocks)
lock (_blocks)
{
return GetFreePagesImpl();
}
@ -411,18 +411,18 @@ namespace Ryujinx.HLE.HOS.Kernel
private ulong GetFreePagesImpl()
{
ulong AvailablePages = 0;
ulong availablePages = 0;
for (int BlockIndex = 0; BlockIndex < BlockOrdersCount; BlockIndex++)
for (int blockIndex = 0; blockIndex < _blockOrdersCount; blockIndex++)
{
KMemoryRegionBlock Block = Blocks[BlockIndex];
KMemoryRegionBlock block = _blocks[blockIndex];
ulong BlockPagesCount = (1UL << Block.Order) / KMemoryManager.PageSize;
ulong blockPagesCount = (1UL << block.Order) / KMemoryManager.PageSize;
AvailablePages += BlockPagesCount * Block.FreeCount;
availablePages += blockPagesCount * block.FreeCount;
}
return AvailablePages;
return availablePages;
}
}
}

View file

@ -5,31 +5,31 @@ namespace Ryujinx.HLE.HOS.Kernel
{
class KPageList : IEnumerable<KPageNode>
{
public LinkedList<KPageNode> Nodes { get; private set; }
public LinkedList<KPageNode> Nodes { get; }
public KPageList()
{
Nodes = new LinkedList<KPageNode>();
}
public KernelResult AddRange(ulong Address, ulong PagesCount)
public KernelResult AddRange(ulong address, ulong pagesCount)
{
if (PagesCount != 0)
if (pagesCount != 0)
{
if (Nodes.Last != null)
{
KPageNode LastNode = Nodes.Last.Value;
KPageNode lastNode = Nodes.Last.Value;
if (LastNode.Address + LastNode.PagesCount * KMemoryManager.PageSize == Address)
if (lastNode.Address + lastNode.PagesCount * KMemoryManager.PageSize == address)
{
Address = LastNode.Address;
PagesCount += LastNode.PagesCount;
address = lastNode.Address;
pagesCount += lastNode.PagesCount;
Nodes.RemoveLast();
}
}
Nodes.AddLast(new KPageNode(Address, PagesCount));
Nodes.AddLast(new KPageNode(address, pagesCount));
}
return KernelResult.Success;
@ -37,34 +37,34 @@ namespace Ryujinx.HLE.HOS.Kernel
public ulong GetPagesCount()
{
ulong Sum = 0;
ulong sum = 0;
foreach (KPageNode Node in Nodes)
foreach (KPageNode node in Nodes)
{
Sum += Node.PagesCount;
sum += node.PagesCount;
}
return Sum;
return sum;
}
public bool IsEqual(KPageList Other)
public bool IsEqual(KPageList other)
{
LinkedListNode<KPageNode> ThisNode = Nodes.First;
LinkedListNode<KPageNode> OtherNode = Other.Nodes.First;
LinkedListNode<KPageNode> thisNode = Nodes.First;
LinkedListNode<KPageNode> otherNode = other.Nodes.First;
while (ThisNode != null && OtherNode != null)
while (thisNode != null && otherNode != null)
{
if (ThisNode.Value.Address != OtherNode.Value.Address ||
ThisNode.Value.PagesCount != OtherNode.Value.PagesCount)
if (thisNode.Value.Address != otherNode.Value.Address ||
thisNode.Value.PagesCount != otherNode.Value.PagesCount)
{
return false;
}
ThisNode = ThisNode.Next;
OtherNode = OtherNode.Next;
thisNode = thisNode.Next;
otherNode = otherNode.Next;
}
return ThisNode == null && OtherNode == null;
return thisNode == null && otherNode == null;
}
public IEnumerator<KPageNode> GetEnumerator()

View file

@ -5,10 +5,10 @@ namespace Ryujinx.HLE.HOS.Kernel
public ulong Address;
public ulong PagesCount;
public KPageNode(ulong Address, ulong PagesCount)
public KPageNode(ulong address, ulong pagesCount)
{
this.Address = Address;
this.PagesCount = PagesCount;
Address = address;
PagesCount = pagesCount;
}
}
}

View file

@ -2,25 +2,25 @@ namespace Ryujinx.HLE.HOS.Kernel
{
class KPort : KAutoObject
{
public KServerPort ServerPort { get; private set; }
public KClientPort ClientPort { get; private set; }
public KServerPort ServerPort { get; }
public KClientPort ClientPort { get; }
private long NameAddress;
private bool IsLight;
private long _nameAddress;
private bool _isLight;
public KPort(Horizon System) : base(System)
public KPort(Horizon system) : base(system)
{
ServerPort = new KServerPort(System);
ClientPort = new KClientPort(System);
ServerPort = new KServerPort(system);
ClientPort = new KClientPort(system);
}
public void Initialize(int MaxSessions, bool IsLight, long NameAddress)
public void Initialize(int maxSessions, bool isLight, long nameAddress)
{
ServerPort.Initialize(this);
ClientPort.Initialize(this, MaxSessions);
ClientPort.Initialize(this, maxSessions);
this.IsLight = IsLight;
this.NameAddress = NameAddress;
_isLight = isLight;
_nameAddress = nameAddress;
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -4,8 +4,8 @@ namespace Ryujinx.HLE.HOS.Kernel
{
class KProcessCapabilities
{
public byte[] SvcAccessMask { get; private set; }
public byte[] IrqAccessMask { get; private set; }
public byte[] SvcAccessMask { get; }
public byte[] IrqAccessMask { get; }
public long AllowedCpuCoresMask { get; private set; }
public long AllowedThreadPriosMask { get; private set; }
@ -21,91 +21,91 @@ namespace Ryujinx.HLE.HOS.Kernel
IrqAccessMask = new byte[0x80];
}
public KernelResult InitializeForKernel(int[] Caps, KMemoryManager MemoryManager)
public KernelResult InitializeForKernel(int[] caps, KMemoryManager memoryManager)
{
AllowedCpuCoresMask = 0xf;
AllowedThreadPriosMask = -1;
DebuggingFlags &= ~3;
KernelReleaseVersion = KProcess.KernelVersionPacked;
return Parse(Caps, MemoryManager);
return Parse(caps, memoryManager);
}
public KernelResult InitializeForUser(int[] Caps, KMemoryManager MemoryManager)
public KernelResult InitializeForUser(int[] caps, KMemoryManager memoryManager)
{
return Parse(Caps, MemoryManager);
return Parse(caps, memoryManager);
}
private KernelResult Parse(int[] Caps, KMemoryManager MemoryManager)
private KernelResult Parse(int[] caps, KMemoryManager memoryManager)
{
int Mask0 = 0;
int Mask1 = 0;
int mask0 = 0;
int mask1 = 0;
for (int Index = 0; Index < Caps.Length; Index++)
for (int index = 0; index < caps.Length; index++)
{
int Cap = Caps[Index];
int cap = caps[index];
if (((Cap + 1) & ~Cap) != 0x40)
if (((cap + 1) & ~cap) != 0x40)
{
KernelResult Result = ParseCapability(Cap, ref Mask0, ref Mask1, MemoryManager);
KernelResult result = ParseCapability(cap, ref mask0, ref mask1, memoryManager);
if (Result != KernelResult.Success)
if (result != KernelResult.Success)
{
return Result;
return result;
}
}
else
{
if ((uint)Index + 1 >= Caps.Length)
if ((uint)index + 1 >= caps.Length)
{
return KernelResult.InvalidCombination;
}
int PrevCap = Cap;
int prevCap = cap;
Cap = Caps[++Index];
cap = caps[++index];
if (((Cap + 1) & ~Cap) != 0x40)
if (((cap + 1) & ~cap) != 0x40)
{
return KernelResult.InvalidCombination;
}
if ((Cap & 0x78000000) != 0)
if ((cap & 0x78000000) != 0)
{
return KernelResult.MaximumExceeded;
}
if ((Cap & 0x7ffff80) == 0)
if ((cap & 0x7ffff80) == 0)
{
return KernelResult.InvalidSize;
}
long Address = ((long)(uint)PrevCap << 5) & 0xffffff000;
long Size = ((long)(uint)Cap << 5) & 0xfffff000;
long address = ((long)(uint)prevCap << 5) & 0xffffff000;
long size = ((long)(uint)cap << 5) & 0xfffff000;
if (((ulong)(Address + Size - 1) >> 36) != 0)
if (((ulong)(address + size - 1) >> 36) != 0)
{
return KernelResult.InvalidAddress;
}
MemoryPermission Perm = (PrevCap >> 31) != 0
MemoryPermission perm = (prevCap >> 31) != 0
? MemoryPermission.Read
: MemoryPermission.ReadAndWrite;
KernelResult Result;
KernelResult result;
if ((Cap >> 31) != 0)
if ((cap >> 31) != 0)
{
Result = MemoryManager.MapNormalMemory(Address, Size, Perm);
result = memoryManager.MapNormalMemory(address, size, perm);
}
else
{
Result = MemoryManager.MapIoMemory(Address, Size, Perm);
result = memoryManager.MapIoMemory(address, size, perm);
}
if (Result != KernelResult.Success)
if (result != KernelResult.Success)
{
return Result;
return result;
}
}
}
@ -113,30 +113,30 @@ namespace Ryujinx.HLE.HOS.Kernel
return KernelResult.Success;
}
private KernelResult ParseCapability(int Cap, ref int Mask0, ref int Mask1, KMemoryManager MemoryManager)
private KernelResult ParseCapability(int cap, ref int mask0, ref int mask1, KMemoryManager memoryManager)
{
int Code = (Cap + 1) & ~Cap;
int code = (cap + 1) & ~cap;
if (Code == 1)
if (code == 1)
{
return KernelResult.InvalidCapability;
}
else if (Code == 0)
else if (code == 0)
{
return KernelResult.Success;
}
int CodeMask = 1 << (32 - BitUtils.CountLeadingZeros32(Code + 1));
int codeMask = 1 << (32 - BitUtils.CountLeadingZeros32(code + 1));
//Check if the property was already set.
if (((Mask0 & CodeMask) & 0x1e008) != 0)
if (((mask0 & codeMask) & 0x1e008) != 0)
{
return KernelResult.InvalidCombination;
}
Mask0 |= CodeMask;
mask0 |= codeMask;
switch (Code)
switch (code)
{
case 8:
{
@ -145,65 +145,65 @@ namespace Ryujinx.HLE.HOS.Kernel
return KernelResult.InvalidCapability;
}
int LowestCpuCore = (Cap >> 16) & 0xff;
int HighestCpuCore = (Cap >> 24) & 0xff;
int lowestCpuCore = (cap >> 16) & 0xff;
int highestCpuCore = (cap >> 24) & 0xff;
if (LowestCpuCore > HighestCpuCore)
if (lowestCpuCore > highestCpuCore)
{
return KernelResult.InvalidCombination;
}
int HighestThreadPrio = (Cap >> 4) & 0x3f;
int LowestThreadPrio = (Cap >> 10) & 0x3f;
int highestThreadPrio = (cap >> 4) & 0x3f;
int lowestThreadPrio = (cap >> 10) & 0x3f;
if (LowestThreadPrio > HighestThreadPrio)
if (lowestThreadPrio > highestThreadPrio)
{
return KernelResult.InvalidCombination;
}
if (HighestCpuCore >= KScheduler.CpuCoresCount)
if (highestCpuCore >= KScheduler.CpuCoresCount)
{
return KernelResult.InvalidCpuCore;
}
AllowedCpuCoresMask = GetMaskFromMinMax(LowestCpuCore, HighestCpuCore);
AllowedThreadPriosMask = GetMaskFromMinMax(LowestThreadPrio, HighestThreadPrio);
AllowedCpuCoresMask = GetMaskFromMinMax(lowestCpuCore, highestCpuCore);
AllowedThreadPriosMask = GetMaskFromMinMax(lowestThreadPrio, highestThreadPrio);
break;
}
case 0x10:
{
int Slot = (Cap >> 29) & 7;
int slot = (cap >> 29) & 7;
int SvcSlotMask = 1 << Slot;
int svcSlotMask = 1 << slot;
if ((Mask1 & SvcSlotMask) != 0)
if ((mask1 & svcSlotMask) != 0)
{
return KernelResult.InvalidCombination;
}
Mask1 |= SvcSlotMask;
mask1 |= svcSlotMask;
int SvcMask = (Cap >> 5) & 0xffffff;
int svcMask = (cap >> 5) & 0xffffff;
int BaseSvc = Slot * 24;
int baseSvc = slot * 24;
for (int Index = 0; Index < 24; Index++)
for (int index = 0; index < 24; index++)
{
if (((SvcMask >> Index) & 1) == 0)
if (((svcMask >> index) & 1) == 0)
{
continue;
}
int SvcId = BaseSvc + Index;
int svcId = baseSvc + index;
if (SvcId > 0x7f)
if (svcId > 0x7f)
{
return KernelResult.MaximumExceeded;
}
SvcAccessMask[SvcId / 8] |= (byte)(1 << (SvcId & 7));
SvcAccessMask[svcId / 8] |= (byte)(1 << (svcId & 7));
}
break;
@ -211,9 +211,9 @@ namespace Ryujinx.HLE.HOS.Kernel
case 0x80:
{
long Address = ((long)(uint)Cap << 4) & 0xffffff000;
long address = ((long)(uint)cap << 4) & 0xffffff000;
MemoryManager.MapIoMemory(Address, KMemoryManager.PageSize, MemoryPermission.ReadAndWrite);
memoryManager.MapIoMemory(address, KMemoryManager.PageSize, MemoryPermission.ReadAndWrite);
break;
}
@ -221,17 +221,17 @@ namespace Ryujinx.HLE.HOS.Kernel
case 0x800:
{
//TODO: GIC distributor check.
int Irq0 = (Cap >> 12) & 0x3ff;
int Irq1 = (Cap >> 22) & 0x3ff;
int irq0 = (cap >> 12) & 0x3ff;
int irq1 = (cap >> 22) & 0x3ff;
if (Irq0 != 0x3ff)
if (irq0 != 0x3ff)
{
IrqAccessMask[Irq0 / 8] |= (byte)(1 << (Irq0 & 7));
IrqAccessMask[irq0 / 8] |= (byte)(1 << (irq0 & 7));
}
if (Irq1 != 0x3ff)
if (irq1 != 0x3ff)
{
IrqAccessMask[Irq1 / 8] |= (byte)(1 << (Irq1 & 7));
IrqAccessMask[irq1 / 8] |= (byte)(1 << (irq1 & 7));
}
break;
@ -239,14 +239,14 @@ namespace Ryujinx.HLE.HOS.Kernel
case 0x2000:
{
int ApplicationType = Cap >> 14;
int applicationType = cap >> 14;
if ((uint)ApplicationType > 7)
if ((uint)applicationType > 7)
{
return KernelResult.ReservedValue;
}
this.ApplicationType = ApplicationType;
ApplicationType = applicationType;
break;
}
@ -254,41 +254,41 @@ namespace Ryujinx.HLE.HOS.Kernel
case 0x4000:
{
//Note: This check is bugged on kernel too, we are just replicating the bug here.
if ((KernelReleaseVersion >> 17) != 0 || Cap < 0x80000)
if ((KernelReleaseVersion >> 17) != 0 || cap < 0x80000)
{
return KernelResult.ReservedValue;
}
KernelReleaseVersion = Cap;
KernelReleaseVersion = cap;
break;
}
case 0x8000:
{
int HandleTableSize = Cap >> 26;
int handleTableSize = cap >> 26;
if ((uint)HandleTableSize > 0x3ff)
if ((uint)handleTableSize > 0x3ff)
{
return KernelResult.ReservedValue;
}
this.HandleTableSize = HandleTableSize;
HandleTableSize = handleTableSize;
break;
}
case 0x10000:
{
int DebuggingFlags = Cap >> 19;
int debuggingFlags = cap >> 19;
if ((uint)DebuggingFlags > 3)
if ((uint)debuggingFlags > 3)
{
return KernelResult.ReservedValue;
}
this.DebuggingFlags &= ~3;
this.DebuggingFlags |= DebuggingFlags;
DebuggingFlags &= ~3;
DebuggingFlags |= debuggingFlags;
break;
}
@ -299,13 +299,13 @@ namespace Ryujinx.HLE.HOS.Kernel
return KernelResult.Success;
}
private static long GetMaskFromMinMax(int Min, int Max)
private static long GetMaskFromMinMax(int min, int max)
{
int Range = Max - Min + 1;
int range = max - min + 1;
long Mask = (1L << Range) - 1;
long mask = (1L << range) - 1;
return Mask << Min;
return mask << min;
}
}
}

View file

@ -2,22 +2,22 @@ namespace Ryujinx.HLE.HOS.Kernel
{
class KReadableEvent : KSynchronizationObject
{
private KEvent Parent;
private KEvent _parent;
private bool Signaled;
private bool _signaled;
public KReadableEvent(Horizon System, KEvent Parent) : base(System)
public KReadableEvent(Horizon system, KEvent parent) : base(system)
{
this.Parent = Parent;
_parent = parent;
}
public override void Signal()
{
System.CriticalSection.Enter();
if (!Signaled)
if (!_signaled)
{
Signaled = true;
_signaled = true;
base.Signal();
}
@ -27,36 +27,36 @@ namespace Ryujinx.HLE.HOS.Kernel
public KernelResult Clear()
{
Signaled = false;
_signaled = false;
return KernelResult.Success;
}
public KernelResult ClearIfSignaled()
{
KernelResult Result;
KernelResult result;
System.CriticalSection.Enter();
if (Signaled)
if (_signaled)
{
Signaled = false;
_signaled = false;
Result = KernelResult.Success;
result = KernelResult.Success;
}
else
{
Result = KernelResult.InvalidState;
result = KernelResult.InvalidState;
}
System.CriticalSection.Leave();
return Result;
return result;
}
public override bool IsSignaled()
{
return Signaled;
return _signaled;
}
}
}

View file

@ -7,127 +7,127 @@ namespace Ryujinx.HLE.HOS.Kernel
{
private const int Time10SecondsMs = 10000;
private long[] Current;
private long[] Limit;
private long[] Available;
private long[] _current;
private long[] _limit;
private long[] _available;
private object LockObj;
private object _lockObj;
private LinkedList<KThread> WaitingThreads;
private LinkedList<KThread> _waitingThreads;
private int WaitingThreadsCount;
private int _waitingThreadsCount;
private Horizon System;
private Horizon _system;
public KResourceLimit(Horizon System)
public KResourceLimit(Horizon system)
{
Current = new long[(int)LimitableResource.Count];
Limit = new long[(int)LimitableResource.Count];
Available = new long[(int)LimitableResource.Count];
_current = new long[(int)LimitableResource.Count];
_limit = new long[(int)LimitableResource.Count];
_available = new long[(int)LimitableResource.Count];
LockObj = new object();
_lockObj = new object();
WaitingThreads = new LinkedList<KThread>();
_waitingThreads = new LinkedList<KThread>();
this.System = System;
_system = system;
}
public bool Reserve(LimitableResource Resource, ulong Amount)
public bool Reserve(LimitableResource resource, ulong amount)
{
return Reserve(Resource, (long)Amount);
return Reserve(resource, (long)amount);
}
public bool Reserve(LimitableResource Resource, long Amount)
public bool Reserve(LimitableResource resource, long amount)
{
return Reserve(Resource, Amount, KTimeManager.ConvertMillisecondsToNanoseconds(Time10SecondsMs));
return Reserve(resource, amount, KTimeManager.ConvertMillisecondsToNanoseconds(Time10SecondsMs));
}
public bool Reserve(LimitableResource Resource, long Amount, long Timeout)
public bool Reserve(LimitableResource resource, long amount, long timeout)
{
long EndTimePoint = KTimeManager.ConvertNanosecondsToMilliseconds(Timeout);
long endTimePoint = KTimeManager.ConvertNanosecondsToMilliseconds(timeout);
EndTimePoint += PerformanceCounter.ElapsedMilliseconds;
endTimePoint += PerformanceCounter.ElapsedMilliseconds;
bool Success = false;
bool success = false;
int Index = GetIndex(Resource);
int index = GetIndex(resource);
lock (LockObj)
lock (_lockObj)
{
long NewCurrent = Current[Index] + Amount;
long newCurrent = _current[index] + amount;
while (NewCurrent > Limit[Index] && Available[Index] + Amount <= Limit[Index])
while (newCurrent > _limit[index] && _available[index] + amount <= _limit[index])
{
WaitingThreadsCount++;
_waitingThreadsCount++;
KConditionVariable.Wait(System, WaitingThreads, LockObj, Timeout);
KConditionVariable.Wait(_system, _waitingThreads, _lockObj, timeout);
WaitingThreadsCount--;
_waitingThreadsCount--;
NewCurrent = Current[Index] + Amount;
newCurrent = _current[index] + amount;
if (Timeout >= 0 && PerformanceCounter.ElapsedMilliseconds > EndTimePoint)
if (timeout >= 0 && PerformanceCounter.ElapsedMilliseconds > endTimePoint)
{
break;
}
}
if (NewCurrent <= Limit[Index])
if (newCurrent <= _limit[index])
{
Current[Index] = NewCurrent;
_current[index] = newCurrent;
Success = true;
success = true;
}
}
return Success;
return success;
}
public void Release(LimitableResource Resource, ulong Amount)
public void Release(LimitableResource resource, ulong amount)
{
Release(Resource, (long)Amount);
Release(resource, (long)amount);
}
public void Release(LimitableResource Resource, long Amount)
public void Release(LimitableResource resource, long amount)
{
Release(Resource, Amount, Amount);
Release(resource, amount, amount);
}
private void Release(LimitableResource Resource, long UsedAmount, long AvailableAmount)
private void Release(LimitableResource resource, long usedAmount, long availableAmount)
{
int Index = GetIndex(Resource);
int index = GetIndex(resource);
lock (LockObj)
lock (_lockObj)
{
Current [Index] -= UsedAmount;
Available[Index] -= AvailableAmount;
_current [index] -= usedAmount;
_available[index] -= availableAmount;
if (WaitingThreadsCount > 0)
if (_waitingThreadsCount > 0)
{
KConditionVariable.NotifyAll(System, WaitingThreads);
KConditionVariable.NotifyAll(_system, _waitingThreads);
}
}
}
public long GetRemainingValue(LimitableResource Resource)
public long GetRemainingValue(LimitableResource resource)
{
int Index = GetIndex(Resource);
int index = GetIndex(resource);
lock (LockObj)
lock (_lockObj)
{
return Limit[Index] - Current[Index];
return _limit[index] - _current[index];
}
}
public KernelResult SetLimitValue(LimitableResource Resource, long Limit)
public KernelResult SetLimitValue(LimitableResource resource, long limit)
{
int Index = GetIndex(Resource);
int index = GetIndex(resource);
lock (LockObj)
lock (_lockObj)
{
if (Current[Index] <= Limit)
if (_current[index] <= limit)
{
this.Limit[Index] = Limit;
_limit[index] = limit;
return KernelResult.Success;
}
@ -138,9 +138,9 @@ namespace Ryujinx.HLE.HOS.Kernel
}
}
private static int GetIndex(LimitableResource Resource)
private static int GetIndex(LimitableResource resource)
{
return (int)Resource;
return (int)resource;
}
}
}

View file

@ -12,17 +12,17 @@ namespace Ryujinx.HLE.HOS.Kernel
private const int PreemptionPriorityCores012 = 59;
private const int PreemptionPriorityCore3 = 63;
private Horizon System;
private Horizon _system;
public KSchedulingData SchedulingData { get; private set; }
public KSchedulingData SchedulingData { get; }
public KCoreContext[] CoreContexts { get; private set; }
public KCoreContext[] CoreContexts { get; }
public bool ThreadReselectionRequested { get; set; }
public KScheduler(Horizon System)
public KScheduler(Horizon system)
{
this.System = System;
_system = system;
SchedulingData = new KSchedulingData();
@ -30,87 +30,87 @@ namespace Ryujinx.HLE.HOS.Kernel
CoreContexts = new KCoreContext[CpuCoresCount];
for (int Core = 0; Core < CpuCoresCount; Core++)
for (int core = 0; core < CpuCoresCount; core++)
{
CoreContexts[Core] = new KCoreContext(this, CoreManager);
CoreContexts[core] = new KCoreContext(this, CoreManager);
}
}
private void PreemptThreads()
{
System.CriticalSection.Enter();
_system.CriticalSection.Enter();
PreemptThread(PreemptionPriorityCores012, 0);
PreemptThread(PreemptionPriorityCores012, 1);
PreemptThread(PreemptionPriorityCores012, 2);
PreemptThread(PreemptionPriorityCore3, 3);
System.CriticalSection.Leave();
_system.CriticalSection.Leave();
}
private void PreemptThread(int Prio, int Core)
private void PreemptThread(int prio, int core)
{
IEnumerable<KThread> ScheduledThreads = SchedulingData.ScheduledThreads(Core);
IEnumerable<KThread> scheduledThreads = SchedulingData.ScheduledThreads(core);
KThread SelectedThread = ScheduledThreads.FirstOrDefault(x => x.DynamicPriority == Prio);
KThread selectedThread = scheduledThreads.FirstOrDefault(x => x.DynamicPriority == prio);
//Yield priority queue.
if (SelectedThread != null)
if (selectedThread != null)
{
SchedulingData.Reschedule(Prio, Core, SelectedThread);
SchedulingData.Reschedule(prio, core, selectedThread);
}
IEnumerable<KThread> SuitableCandidates()
{
foreach (KThread Thread in SchedulingData.SuggestedThreads(Core))
foreach (KThread thread in SchedulingData.SuggestedThreads(core))
{
int SrcCore = Thread.CurrentCore;
int srcCore = thread.CurrentCore;
if (SrcCore >= 0)
if (srcCore >= 0)
{
KThread HighestPrioSrcCore = SchedulingData.ScheduledThreads(SrcCore).FirstOrDefault();
KThread highestPrioSrcCore = SchedulingData.ScheduledThreads(srcCore).FirstOrDefault();
if (HighestPrioSrcCore != null && HighestPrioSrcCore.DynamicPriority < 2)
if (highestPrioSrcCore != null && highestPrioSrcCore.DynamicPriority < 2)
{
break;
}
if (HighestPrioSrcCore == Thread)
if (highestPrioSrcCore == thread)
{
continue;
}
}
//If the candidate was scheduled after the current thread, then it's not worth it.
if (SelectedThread == null || SelectedThread.LastScheduledTime >= Thread.LastScheduledTime)
if (selectedThread == null || selectedThread.LastScheduledTime >= thread.LastScheduledTime)
{
yield return Thread;
yield return thread;
}
}
}
//Select candidate threads that could run on this core.
//Only take into account threads that are not yet selected.
KThread Dst = SuitableCandidates().FirstOrDefault(x => x.DynamicPriority == Prio);
KThread dst = SuitableCandidates().FirstOrDefault(x => x.DynamicPriority == prio);
if (Dst != null)
if (dst != null)
{
SchedulingData.TransferToCore(Prio, Core, Dst);
SchedulingData.TransferToCore(prio, core, dst);
SelectedThread = Dst;
selectedThread = dst;
}
//If the priority of the currently selected thread is lower than preemption priority,
//then allow threads with lower priorities to be selected aswell.
if (SelectedThread != null && SelectedThread.DynamicPriority > Prio)
if (selectedThread != null && selectedThread.DynamicPriority > prio)
{
Func<KThread, bool> Predicate = x => x.DynamicPriority >= SelectedThread.DynamicPriority;
Func<KThread, bool> predicate = x => x.DynamicPriority >= selectedThread.DynamicPriority;
Dst = SuitableCandidates().FirstOrDefault(Predicate);
dst = SuitableCandidates().FirstOrDefault(predicate);
if (Dst != null)
if (dst != null)
{
SchedulingData.TransferToCore(Dst.DynamicPriority, Core, Dst);
SchedulingData.TransferToCore(dst.DynamicPriority, core, dst);
}
}
@ -121,52 +121,52 @@ namespace Ryujinx.HLE.HOS.Kernel
{
ThreadReselectionRequested = false;
for (int Core = 0; Core < CpuCoresCount; Core++)
for (int core = 0; core < CpuCoresCount; core++)
{
KThread Thread = SchedulingData.ScheduledThreads(Core).FirstOrDefault();
KThread thread = SchedulingData.ScheduledThreads(core).FirstOrDefault();
CoreContexts[Core].SelectThread(Thread);
CoreContexts[core].SelectThread(thread);
}
for (int Core = 0; Core < CpuCoresCount; Core++)
for (int core = 0; core < CpuCoresCount; core++)
{
//If the core is not idle (there's already a thread running on it),
//then we don't need to attempt load balancing.
if (SchedulingData.ScheduledThreads(Core).Any())
if (SchedulingData.ScheduledThreads(core).Any())
{
continue;
}
int[] SrcCoresHighestPrioThreads = new int[CpuCoresCount];
int[] srcCoresHighestPrioThreads = new int[CpuCoresCount];
int SrcCoresHighestPrioThreadsCount = 0;
int srcCoresHighestPrioThreadsCount = 0;
KThread Dst = null;
KThread dst = null;
//Select candidate threads that could run on this core.
//Give preference to threads that are not yet selected.
foreach (KThread Thread in SchedulingData.SuggestedThreads(Core))
foreach (KThread thread in SchedulingData.SuggestedThreads(core))
{
if (Thread.CurrentCore < 0 || Thread != CoreContexts[Thread.CurrentCore].SelectedThread)
if (thread.CurrentCore < 0 || thread != CoreContexts[thread.CurrentCore].SelectedThread)
{
Dst = Thread;
dst = thread;
break;
}
SrcCoresHighestPrioThreads[SrcCoresHighestPrioThreadsCount++] = Thread.CurrentCore;
srcCoresHighestPrioThreads[srcCoresHighestPrioThreadsCount++] = thread.CurrentCore;
}
//Not yet selected candidate found.
if (Dst != null)
if (dst != null)
{
//Priorities < 2 are used for the kernel message dispatching
//threads, we should skip load balancing entirely.
if (Dst.DynamicPriority >= 2)
if (dst.DynamicPriority >= 2)
{
SchedulingData.TransferToCore(Dst.DynamicPriority, Core, Dst);
SchedulingData.TransferToCore(dst.DynamicPriority, core, dst);
CoreContexts[Core].SelectThread(Dst);
CoreContexts[core].SelectThread(dst);
}
continue;
@ -174,23 +174,23 @@ namespace Ryujinx.HLE.HOS.Kernel
//All candiates are already selected, choose the best one
//(the first one that doesn't make the source core idle if moved).
for (int Index = 0; Index < SrcCoresHighestPrioThreadsCount; Index++)
for (int index = 0; index < srcCoresHighestPrioThreadsCount; index++)
{
int SrcCore = SrcCoresHighestPrioThreads[Index];
int srcCore = srcCoresHighestPrioThreads[index];
KThread Src = SchedulingData.ScheduledThreads(SrcCore).ElementAtOrDefault(1);
KThread src = SchedulingData.ScheduledThreads(srcCore).ElementAtOrDefault(1);
if (Src != null)
if (src != null)
{
//Run the second thread on the queue on the source core,
//move the first one to the current core.
KThread OrigSelectedCoreSrc = CoreContexts[SrcCore].SelectedThread;
KThread origSelectedCoreSrc = CoreContexts[srcCore].SelectedThread;
CoreContexts[SrcCore].SelectThread(Src);
CoreContexts[srcCore].SelectThread(src);
SchedulingData.TransferToCore(OrigSelectedCoreSrc.DynamicPriority, Core, OrigSelectedCoreSrc);
SchedulingData.TransferToCore(origSelectedCoreSrc.DynamicPriority, core, origSelectedCoreSrc);
CoreContexts[Core].SelectThread(OrigSelectedCoreSrc);
CoreContexts[core].SelectThread(origSelectedCoreSrc);
}
}
}
@ -200,11 +200,11 @@ namespace Ryujinx.HLE.HOS.Kernel
{
lock (CoreContexts)
{
for (int Core = 0; Core < CpuCoresCount; Core++)
for (int core = 0; core < CpuCoresCount; core++)
{
if (CoreContexts[Core].CurrentThread?.Context.IsCurrentThread() ?? false)
if (CoreContexts[core].CurrentThread?.Context.IsCurrentThread() ?? false)
{
return CoreContexts[Core].CurrentThread;
return CoreContexts[core].CurrentThread;
}
}
}
@ -222,11 +222,11 @@ namespace Ryujinx.HLE.HOS.Kernel
Dispose(true);
}
protected virtual void Dispose(bool Disposing)
protected virtual void Dispose(bool disposing)
{
if (Disposing)
if (disposing)
{
KeepPreempting = false;
_keepPreempting = false;
}
}
}

View file

@ -4,204 +4,204 @@ namespace Ryujinx.HLE.HOS.Kernel
{
class KSchedulingData
{
private LinkedList<KThread>[][] ScheduledThreadsPerPrioPerCore;
private LinkedList<KThread>[][] SuggestedThreadsPerPrioPerCore;
private LinkedList<KThread>[][] _scheduledThreadsPerPrioPerCore;
private LinkedList<KThread>[][] _suggestedThreadsPerPrioPerCore;
private long[] ScheduledPrioritiesPerCore;
private long[] SuggestedPrioritiesPerCore;
private long[] _scheduledPrioritiesPerCore;
private long[] _suggestedPrioritiesPerCore;
public KSchedulingData()
{
SuggestedThreadsPerPrioPerCore = new LinkedList<KThread>[KScheduler.PrioritiesCount][];
ScheduledThreadsPerPrioPerCore = new LinkedList<KThread>[KScheduler.PrioritiesCount][];
_suggestedThreadsPerPrioPerCore = new LinkedList<KThread>[KScheduler.PrioritiesCount][];
_scheduledThreadsPerPrioPerCore = new LinkedList<KThread>[KScheduler.PrioritiesCount][];
for (int Prio = 0; Prio < KScheduler.PrioritiesCount; Prio++)
for (int prio = 0; prio < KScheduler.PrioritiesCount; prio++)
{
SuggestedThreadsPerPrioPerCore[Prio] = new LinkedList<KThread>[KScheduler.CpuCoresCount];
ScheduledThreadsPerPrioPerCore[Prio] = new LinkedList<KThread>[KScheduler.CpuCoresCount];
_suggestedThreadsPerPrioPerCore[prio] = new LinkedList<KThread>[KScheduler.CpuCoresCount];
_scheduledThreadsPerPrioPerCore[prio] = new LinkedList<KThread>[KScheduler.CpuCoresCount];
for (int Core = 0; Core < KScheduler.CpuCoresCount; Core++)
for (int core = 0; core < KScheduler.CpuCoresCount; core++)
{
SuggestedThreadsPerPrioPerCore[Prio][Core] = new LinkedList<KThread>();
ScheduledThreadsPerPrioPerCore[Prio][Core] = new LinkedList<KThread>();
_suggestedThreadsPerPrioPerCore[prio][core] = new LinkedList<KThread>();
_scheduledThreadsPerPrioPerCore[prio][core] = new LinkedList<KThread>();
}
}
ScheduledPrioritiesPerCore = new long[KScheduler.CpuCoresCount];
SuggestedPrioritiesPerCore = new long[KScheduler.CpuCoresCount];
_scheduledPrioritiesPerCore = new long[KScheduler.CpuCoresCount];
_suggestedPrioritiesPerCore = new long[KScheduler.CpuCoresCount];
}
public IEnumerable<KThread> SuggestedThreads(int Core)
public IEnumerable<KThread> SuggestedThreads(int core)
{
return Iterate(SuggestedThreadsPerPrioPerCore, SuggestedPrioritiesPerCore, Core);
return Iterate(_suggestedThreadsPerPrioPerCore, _suggestedPrioritiesPerCore, core);
}
public IEnumerable<KThread> ScheduledThreads(int Core)
public IEnumerable<KThread> ScheduledThreads(int core)
{
return Iterate(ScheduledThreadsPerPrioPerCore, ScheduledPrioritiesPerCore, Core);
return Iterate(_scheduledThreadsPerPrioPerCore, _scheduledPrioritiesPerCore, core);
}
private IEnumerable<KThread> Iterate(LinkedList<KThread>[][] ListPerPrioPerCore, long[] Prios, int Core)
private IEnumerable<KThread> Iterate(LinkedList<KThread>[][] listPerPrioPerCore, long[] prios, int core)
{
long PrioMask = Prios[Core];
long prioMask = prios[core];
int Prio = CountTrailingZeros(PrioMask);
int prio = CountTrailingZeros(prioMask);
PrioMask &= ~(1L << Prio);
prioMask &= ~(1L << prio);
while (Prio < KScheduler.PrioritiesCount)
while (prio < KScheduler.PrioritiesCount)
{
LinkedList<KThread> List = ListPerPrioPerCore[Prio][Core];
LinkedList<KThread> list = listPerPrioPerCore[prio][core];
LinkedListNode<KThread> Node = List.First;
LinkedListNode<KThread> node = list.First;
while (Node != null)
while (node != null)
{
yield return Node.Value;
yield return node.Value;
Node = Node.Next;
node = node.Next;
}
Prio = CountTrailingZeros(PrioMask);
prio = CountTrailingZeros(prioMask);
PrioMask &= ~(1L << Prio);
prioMask &= ~(1L << prio);
}
}
private int CountTrailingZeros(long Value)
private int CountTrailingZeros(long value)
{
int Count = 0;
int count = 0;
while (((Value >> Count) & 0xf) == 0 && Count < 64)
while (((value >> count) & 0xf) == 0 && count < 64)
{
Count += 4;
count += 4;
}
while (((Value >> Count) & 1) == 0 && Count < 64)
while (((value >> count) & 1) == 0 && count < 64)
{
Count++;
count++;
}
return Count;
return count;
}
public void TransferToCore(int Prio, int DstCore, KThread Thread)
public void TransferToCore(int prio, int dstCore, KThread thread)
{
bool Schedulable = Thread.DynamicPriority < KScheduler.PrioritiesCount;
bool schedulable = thread.DynamicPriority < KScheduler.PrioritiesCount;
int SrcCore = Thread.CurrentCore;
int srcCore = thread.CurrentCore;
Thread.CurrentCore = DstCore;
thread.CurrentCore = dstCore;
if (SrcCore == DstCore || !Schedulable)
if (srcCore == dstCore || !schedulable)
{
return;
}
if (SrcCore >= 0)
if (srcCore >= 0)
{
Unschedule(Prio, SrcCore, Thread);
Unschedule(prio, srcCore, thread);
}
if (DstCore >= 0)
if (dstCore >= 0)
{
Unsuggest(Prio, DstCore, Thread);
Schedule(Prio, DstCore, Thread);
Unsuggest(prio, dstCore, thread);
Schedule(prio, dstCore, thread);
}
if (SrcCore >= 0)
if (srcCore >= 0)
{
Suggest(Prio, SrcCore, Thread);
Suggest(prio, srcCore, thread);
}
}
public void Suggest(int Prio, int Core, KThread Thread)
public void Suggest(int prio, int core, KThread thread)
{
if (Prio >= KScheduler.PrioritiesCount)
if (prio >= KScheduler.PrioritiesCount)
{
return;
}
Thread.SiblingsPerCore[Core] = SuggestedQueue(Prio, Core).AddFirst(Thread);
thread.SiblingsPerCore[core] = SuggestedQueue(prio, core).AddFirst(thread);
SuggestedPrioritiesPerCore[Core] |= 1L << Prio;
_suggestedPrioritiesPerCore[core] |= 1L << prio;
}
public void Unsuggest(int Prio, int Core, KThread Thread)
public void Unsuggest(int prio, int core, KThread thread)
{
if (Prio >= KScheduler.PrioritiesCount)
if (prio >= KScheduler.PrioritiesCount)
{
return;
}
LinkedList<KThread> Queue = SuggestedQueue(Prio, Core);
LinkedList<KThread> queue = SuggestedQueue(prio, core);
Queue.Remove(Thread.SiblingsPerCore[Core]);
queue.Remove(thread.SiblingsPerCore[core]);
if (Queue.First == null)
if (queue.First == null)
{
SuggestedPrioritiesPerCore[Core] &= ~(1L << Prio);
_suggestedPrioritiesPerCore[core] &= ~(1L << prio);
}
}
public void Schedule(int Prio, int Core, KThread Thread)
public void Schedule(int prio, int core, KThread thread)
{
if (Prio >= KScheduler.PrioritiesCount)
if (prio >= KScheduler.PrioritiesCount)
{
return;
}
Thread.SiblingsPerCore[Core] = ScheduledQueue(Prio, Core).AddLast(Thread);
thread.SiblingsPerCore[core] = ScheduledQueue(prio, core).AddLast(thread);
ScheduledPrioritiesPerCore[Core] |= 1L << Prio;
_scheduledPrioritiesPerCore[core] |= 1L << prio;
}
public void SchedulePrepend(int Prio, int Core, KThread Thread)
public void SchedulePrepend(int prio, int core, KThread thread)
{
if (Prio >= KScheduler.PrioritiesCount)
if (prio >= KScheduler.PrioritiesCount)
{
return;
}
Thread.SiblingsPerCore[Core] = ScheduledQueue(Prio, Core).AddFirst(Thread);
thread.SiblingsPerCore[core] = ScheduledQueue(prio, core).AddFirst(thread);
ScheduledPrioritiesPerCore[Core] |= 1L << Prio;
_scheduledPrioritiesPerCore[core] |= 1L << prio;
}
public void Reschedule(int Prio, int Core, KThread Thread)
public void Reschedule(int prio, int core, KThread thread)
{
LinkedList<KThread> Queue = ScheduledQueue(Prio, Core);
LinkedList<KThread> queue = ScheduledQueue(prio, core);
Queue.Remove(Thread.SiblingsPerCore[Core]);
queue.Remove(thread.SiblingsPerCore[core]);
Thread.SiblingsPerCore[Core] = Queue.AddLast(Thread);
thread.SiblingsPerCore[core] = queue.AddLast(thread);
}
public void Unschedule(int Prio, int Core, KThread Thread)
public void Unschedule(int prio, int core, KThread thread)
{
if (Prio >= KScheduler.PrioritiesCount)
if (prio >= KScheduler.PrioritiesCount)
{
return;
}
LinkedList<KThread> Queue = ScheduledQueue(Prio, Core);
LinkedList<KThread> queue = ScheduledQueue(prio, core);
Queue.Remove(Thread.SiblingsPerCore[Core]);
queue.Remove(thread.SiblingsPerCore[core]);
if (Queue.First == null)
if (queue.First == null)
{
ScheduledPrioritiesPerCore[Core] &= ~(1L << Prio);
_scheduledPrioritiesPerCore[core] &= ~(1L << prio);
}
}
private LinkedList<KThread> SuggestedQueue(int Prio, int Core)
private LinkedList<KThread> SuggestedQueue(int prio, int core)
{
return SuggestedThreadsPerPrioPerCore[Prio][Core];
return _suggestedThreadsPerPrioPerCore[prio][core];
}
private LinkedList<KThread> ScheduledQueue(int Prio, int Core)
private LinkedList<KThread> ScheduledQueue(int prio, int core)
{
return ScheduledThreadsPerPrioPerCore[Prio][Core];
return _scheduledThreadsPerPrioPerCore[prio][core];
}
}
}

View file

@ -2,13 +2,13 @@ namespace Ryujinx.HLE.HOS.Kernel
{
class KServerPort : KSynchronizationObject
{
private KPort Parent;
private KPort _parent;
public KServerPort(Horizon System) : base(System) { }
public KServerPort(Horizon system) : base(system) { }
public void Initialize(KPort Parent)
public void Initialize(KPort parent)
{
this.Parent = Parent;
_parent = parent;
}
}
}

View file

@ -5,14 +5,14 @@ namespace Ryujinx.HLE.HOS.Kernel
{
class KSession : IDisposable
{
public IpcService Service { get; private set; }
public IpcService Service { get; }
public string ServiceName { get; private set; }
public string ServiceName { get; }
public KSession(IpcService Service, string ServiceName)
public KSession(IpcService service, string serviceName)
{
this.Service = Service;
this.ServiceName = ServiceName;
Service = service;
ServiceName = serviceName;
}
public void Dispose()
@ -20,11 +20,11 @@ namespace Ryujinx.HLE.HOS.Kernel
Dispose(true);
}
protected virtual void Dispose(bool Disposing)
protected virtual void Dispose(bool disposing)
{
if (Disposing && Service is IDisposable DisposableService)
if (disposing && Service is IDisposable disposableService)
{
DisposableService.Dispose();
disposableService.Dispose();
}
}
}

View file

@ -4,65 +4,65 @@ namespace Ryujinx.HLE.HOS.Kernel
{
class KSharedMemory
{
private KPageList PageList;
private KPageList _pageList;
private long OwnerPid;
private long _ownerPid;
private MemoryPermission OwnerPermission;
private MemoryPermission UserPermission;
private MemoryPermission _ownerPermission;
private MemoryPermission _userPermission;
public KSharedMemory(
KPageList PageList,
long OwnerPid,
MemoryPermission OwnerPermission,
MemoryPermission UserPermission)
KPageList pageList,
long ownerPid,
MemoryPermission ownerPermission,
MemoryPermission userPermission)
{
this.PageList = PageList;
this.OwnerPid = OwnerPid;
this.OwnerPermission = OwnerPermission;
this.UserPermission = UserPermission;
_pageList = pageList;
_ownerPid = ownerPid;
_ownerPermission = ownerPermission;
_userPermission = userPermission;
}
public KernelResult MapIntoProcess(
KMemoryManager MemoryManager,
ulong Address,
ulong Size,
KProcess Process,
MemoryPermission Permission)
KMemoryManager memoryManager,
ulong address,
ulong size,
KProcess process,
MemoryPermission permission)
{
ulong PagesCountRounded = BitUtils.DivRoundUp(Size, KMemoryManager.PageSize);
ulong pagesCountRounded = BitUtils.DivRoundUp(size, KMemoryManager.PageSize);
if (PageList.GetPagesCount() != PagesCountRounded)
if (_pageList.GetPagesCount() != pagesCountRounded)
{
return KernelResult.InvalidSize;
}
MemoryPermission ExpectedPermission = Process.Pid == OwnerPid
? OwnerPermission
: UserPermission;
MemoryPermission expectedPermission = process.Pid == _ownerPid
? _ownerPermission
: _userPermission;
if (Permission != ExpectedPermission)
if (permission != expectedPermission)
{
return KernelResult.InvalidPermission;
}
return MemoryManager.MapPages(Address, PageList, MemoryState.SharedMemory, Permission);
return memoryManager.MapPages(address, _pageList, MemoryState.SharedMemory, permission);
}
public KernelResult UnmapFromProcess(
KMemoryManager MemoryManager,
ulong Address,
ulong Size,
KProcess Process)
KMemoryManager memoryManager,
ulong address,
ulong size,
KProcess process)
{
ulong PagesCountRounded = BitUtils.DivRoundUp(Size, KMemoryManager.PageSize);
ulong pagesCountRounded = BitUtils.DivRoundUp(size, KMemoryManager.PageSize);
if (PageList.GetPagesCount() != PagesCountRounded)
if (_pageList.GetPagesCount() != pagesCountRounded)
{
return KernelResult.InvalidSize;
}
return MemoryManager.UnmapPages(Address, PageList, MemoryState.SharedMemory);
return memoryManager.UnmapPages(address, _pageList, MemoryState.SharedMemory);
}
}
}

View file

@ -4,46 +4,46 @@ namespace Ryujinx.HLE.HOS.Kernel
{
class KSlabHeap
{
private LinkedList<ulong> Items;
private LinkedList<ulong> _items;
public KSlabHeap(ulong Pa, ulong ItemSize, ulong Size)
public KSlabHeap(ulong pa, ulong itemSize, ulong size)
{
Items = new LinkedList<ulong>();
_items = new LinkedList<ulong>();
int ItemsCount = (int)(Size / ItemSize);
int itemsCount = (int)(size / itemSize);
for (int Index = 0; Index < ItemsCount; Index++)
for (int index = 0; index < itemsCount; index++)
{
Items.AddLast(Pa);
_items.AddLast(pa);
Pa += ItemSize;
pa += itemSize;
}
}
public bool TryGetItem(out ulong Pa)
public bool TryGetItem(out ulong pa)
{
lock (Items)
lock (_items)
{
if (Items.First != null)
if (_items.First != null)
{
Pa = Items.First.Value;
pa = _items.First.Value;
Items.RemoveFirst();
_items.RemoveFirst();
return true;
}
}
Pa = 0;
pa = 0;
return false;
}
public void Free(ulong Pa)
public void Free(ulong pa)
{
lock (Items)
lock (_items)
{
Items.AddFirst(Pa);
_items.AddFirst(pa);
}
}
}

Some files were not shown because too many files have changed in this diff Show more