コード例 #1
0
ファイル: SvcThreadSync.cs プロジェクト: tangyiyong/Ryujinx
        private void SvcWaitForAddress(CpuThreadState ThreadState)
        {
            long            Address = (long)ThreadState.X0;
            ArbitrationType Type    = (ArbitrationType)ThreadState.X1;
            int             Value   = (int)ThreadState.X2;
            long            Timeout = (long)ThreadState.X3;

            Logger.PrintDebug(LogClass.KernelSvc,
                              "Address = 0x" + Address.ToString("x16") + ", " +
                              "Type = " + Type.ToString() + ", " +
                              "Value = 0x" + Value.ToString("x8") + ", " +
                              "Timeout = 0x" + Timeout.ToString("x16"));

            if (IsPointingInsideKernel(Address))
            {
                Logger.PrintWarning(LogClass.KernelSvc, $"Invalid address 0x{Address:x16}!");

                ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);

                return;
            }

            if (IsAddressNotWordAligned(Address))
            {
                Logger.PrintWarning(LogClass.KernelSvc, $"Unaligned address 0x{Address:x16}!");

                ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidAddress);

                return;
            }

            long Result;

            switch (Type)
            {
            case ArbitrationType.WaitIfLessThan:
                Result = System.AddressArbiter.WaitForAddressIfLessThan(Memory, Address, Value, false, Timeout);
                break;

            case ArbitrationType.DecrementAndWaitIfLessThan:
                Result = System.AddressArbiter.WaitForAddressIfLessThan(Memory, Address, Value, true, Timeout);
                break;

            case ArbitrationType.WaitIfEqual:
                Result = System.AddressArbiter.WaitForAddressIfEqual(Memory, Address, Value, Timeout);
                break;

            default:
                Result = MakeError(ErrorModule.Kernel, KernelErr.InvalidEnumValue);
                break;
            }

            if (Result != 0)
            {
                Logger.PrintWarning(LogClass.KernelSvc, $"Operation failed with error 0x{Result:x}!");
            }

            ThreadState.X0 = (ulong)Result;
        }
コード例 #2
0
        private void SvcWaitForAddress(AThreadState ThreadState)
        {
            long            Address = (long)ThreadState.X0;
            ArbitrationType Type    = (ArbitrationType)ThreadState.X1;
            int             Value   = (int)ThreadState.X2;
            ulong           Timeout = ThreadState.X3;

            Ns.Log.PrintDebug(LogClass.KernelSvc,
                              "Address = " + Address.ToString("x16") + ", " +
                              "ArbitrationType = " + Type.ToString() + ", " +
                              "Value = " + Value.ToString("x8") + ", " +
                              "Timeout = " + Timeout.ToString("x16"));

            if (IsPointingInsideKernel(Address))
            {
                Ns.Log.PrintWarning(LogClass.KernelSvc, $"Invalid address 0x{Address:x16}!");

                ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);

                return;
            }

            if (IsWordAddressUnaligned(Address))
            {
                Ns.Log.PrintWarning(LogClass.KernelSvc, $"Unaligned address 0x{Address:x16}!");

                ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidAddress);

                return;
            }

            switch (Type)
            {
            case ArbitrationType.WaitIfLessThan:
                ThreadState.X0 = AddressArbiter.WaitForAddressIfLessThan(Process, ThreadState, Memory, Address, Value, Timeout, false);
                break;

            case ArbitrationType.DecrementAndWaitIfLessThan:
                ThreadState.X0 = AddressArbiter.WaitForAddressIfLessThan(Process, ThreadState, Memory, Address, Value, Timeout, true);
                break;

            case ArbitrationType.WaitIfEqual:
                ThreadState.X0 = AddressArbiter.WaitForAddressIfEqual(Process, ThreadState, Memory, Address, Value, Timeout);
                break;

            default:
                ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidEnumValue);
                break;
            }
        }
コード例 #3
0
ファイル: SvcThreadSync.cs プロジェクト: zpoo32/Ryujinx
        private KernelResult WaitForAddress(ulong address, ArbitrationType type, int value, long timeout)
        {
            if (IsPointingInsideKernel(address))
            {
                return(KernelResult.InvalidMemState);
            }

            if (IsAddressNotWordAligned(address))
            {
                return(KernelResult.InvalidAddress);
            }

            KProcess currentProcess = _system.Scheduler.GetCurrentProcess();

            KernelResult result;

            switch (type)
            {
            case ArbitrationType.WaitIfLessThan:
                result = currentProcess.AddressArbiter.WaitForAddressIfLessThan(address, value, false, timeout);
                break;

            case ArbitrationType.DecrementAndWaitIfLessThan:
                result = currentProcess.AddressArbiter.WaitForAddressIfLessThan(address, value, true, timeout);
                break;

            case ArbitrationType.WaitIfEqual:
                result = currentProcess.AddressArbiter.WaitForAddressIfEqual(address, value, timeout);
                break;

            default:
                result = KernelResult.InvalidEnumValue;
                break;
            }

            return(result);
        }
コード例 #4
0
ファイル: Syscall64.cs プロジェクト: jduncanator/Ryujinx
 public KernelResult WaitForAddress64([R(0)] ulong address, [R(1)] ArbitrationType type, [R(2)] int value, [R(3)] long timeout)
 {
     return(_syscall.WaitForAddress(address, type, value, timeout));
 }
コード例 #5
0
ファイル: SvcThreadSync.cs プロジェクト: zpoo32/Ryujinx
 public KernelResult WaitForAddress64(ulong address, ArbitrationType type, int value, long timeout)
 {
     return(WaitForAddress(address, type, value, timeout));
 }
コード例 #6
0
ファイル: Syscall32.cs プロジェクト: ski982/Ryujinx-1
        public KernelResult WaitForAddress32([R(0)] uint address, [R(1)] ArbitrationType type, [R(2)] int value, [R(3)] uint timeoutLow, [R(4)] uint timeoutHigh)
        {
            long timeout = (long)(timeoutLow | ((ulong)timeoutHigh << 32));

            return(_syscall.WaitForAddress(address, type, value, timeout));
        }
コード例 #7
0
ファイル: OrganArbitrator.cs プロジェクト: hol353/ApsimX
        /// <summary>Does the uptake.</summary>
        /// <param name="Organs">The organs.</param>
        /// <param name="BAT">The bat.</param>
        /// <param name="Option">The option.</param>
        public virtual void DoUptake(IArbitration[] Organs, BiomassArbitrationType BAT,  ArbitrationType Option)
        {
            double BiomassTakenUp = 0;
            if (BAT.TotalUptakeSupply > 0.00000000001)
            {
                // Calculate how much uptake N each demanding organ is allocated based on relative demands
                if (Option == ArbitrationType.RelativeAllocation)
                    RelativeAllocation(Organs, BAT.TotalUptakeSupply, ref BiomassTakenUp, BAT);
                if (Option == ArbitrationType.PriorityAllocation)
                    PriorityAllocation(Organs, BAT.TotalUptakeSupply, ref BiomassTakenUp, BAT);
                if (Option == ArbitrationType.PriorityThenRelativeAllocation)
                    PrioritythenRelativeAllocation(Organs, BAT.TotalUptakeSupply, ref BiomassTakenUp, BAT);
                if (Option == ArbitrationType.RelativeAllocationSinglePass)
                    RelativeAllocationSinglePass(Organs, BAT.TotalUptakeSupply, ref BiomassTakenUp, BAT);

                // Then calculate how much N is taken up by each supplying organ based on relative uptake supply
                for (int i = 0; i < Organs.Length; i++)
                {
                    if (BAT.UptakeSupply[i] > 0.00000000001)
                    {
                        double RelativeSupply = BAT.UptakeSupply[i] / BAT.TotalUptakeSupply;
                        BAT.Uptake[i] += BiomassTakenUp * RelativeSupply;
                    }
                }
            }
        }
コード例 #8
0
ファイル: OrganArbitrator.cs プロジェクト: hol353/ApsimX
        /// <summary>Does the retranslocation.</summary>
        /// <param name="Organs">The organs.</param>
        /// <param name="BAT">The bat.</param>
        /// <param name="Option">The option.</param>
        public virtual void DoRetranslocation(IArbitration[] Organs, BiomassArbitrationType BAT, ArbitrationType Option)
        {
            double BiomassRetranslocated = 0;
            if (BAT.TotalRetranslocationSupply > 0.00000000001)
            {
                // Calculate how much retranslocation N (and associated biomass) each demanding organ is allocated based on relative demands
                if (Option == ArbitrationType.RelativeAllocation)
                    RelativeAllocation(Organs, BAT.TotalRetranslocationSupply, ref BiomassRetranslocated, BAT);
                if (Option == ArbitrationType.PriorityAllocation)
                    PriorityAllocation(Organs, BAT.TotalRetranslocationSupply, ref BiomassRetranslocated, BAT);
                if (Option == ArbitrationType.PriorityThenRelativeAllocation)
                    PrioritythenRelativeAllocation(Organs, BAT.TotalRetranslocationSupply, ref BiomassRetranslocated, BAT);
                if (Option == ArbitrationType.RelativeAllocationSinglePass)
                    RelativeAllocationSinglePass(Organs, BAT.TotalRetranslocationSupply, ref BiomassRetranslocated, BAT);

                // Then calculate how much N (and associated biomass) is retranslocated from each supplying organ based on relative retranslocation supply
                for (int i = 0; i < Organs.Length; i++)
                {
                    if (BAT.RetranslocationSupply[i] > 0.00000000001)
                    {
                        double RelativeSupply = BAT.RetranslocationSupply[i] / BAT.TotalRetranslocationSupply;
                        BAT.Retranslocation[i] += BiomassRetranslocated * RelativeSupply;
                    }
                }
            }
        }
コード例 #9
0
ファイル: OrganArbitrator.cs プロジェクト: hol353/ApsimX
        /// <summary>Does the fixation.</summary>
        /// <param name="Organs">The organs.</param>
        /// <param name="BAT">The bat.</param>
        /// <param name="Option">The option.</param>
        /// <exception cref="System.Exception">Crop is trying to Fix excessive amounts of BAT.  Check partitioning coefficients are giving realistic nodule size and that FixationRatePotential is realistic</exception>
        public virtual void DoFixation(IArbitration[] Organs, BiomassArbitrationType BAT, ArbitrationType Option)
        {
            double BiomassFixed = 0;
            if (BAT.TotalFixationSupply > 0.00000000001)
            {
                // Calculate how much fixed resource each demanding organ is allocated based on relative demands
                if (Option == ArbitrationType.RelativeAllocation)
                    RelativeAllocation(Organs, BAT.TotalFixationSupply, ref BiomassFixed, BAT);
                if (Option == ArbitrationType.PriorityAllocation)
                    PriorityAllocation(Organs, BAT.TotalFixationSupply, ref BiomassFixed, BAT);
                if (Option == ArbitrationType.PriorityThenRelativeAllocation)
                    PrioritythenRelativeAllocation(Organs, BAT.TotalFixationSupply, ref BiomassFixed, BAT);
                if (Option == ArbitrationType.RelativeAllocationSinglePass)
                    RelativeAllocationSinglePass(Organs, BAT.TotalFixationSupply, ref BiomassFixed, BAT);

                //Set the sink limitation variable.  BAT.NotAllocated changes after each allocation step so it must be caught here and assigned as sink limitation
                BAT.SinkLimitation = BAT.NotAllocated;

                // Then calculate how much resource is fixed from each supplying organ based on relative fixation supply
                if (BiomassFixed > 0)
                {
                    for (int i = 0; i < Organs.Length; i++)
                    {
                        if (BAT.FixationSupply[i] > 0.00000000001)
                        {
                            double RelativeSupply = BAT.FixationSupply[i] / BAT.TotalFixationSupply;
                            BAT.Fixation[i] = BiomassFixed * RelativeSupply;
                            double Respiration = BiomassFixed * RelativeSupply * Organs[i].NFixationCost;  //Calculalte how much respirtion is associated with fixation
                            DM.Respiration[i] = Respiration; // allocate it to the organ
                        }
                        DM.TotalRespiration = MathUtilities.Sum(DM.Respiration);
                    }
                }

                // Work out the amount of biomass (if any) lost due to the cost of N fixation
                if (DM.TotalRespiration <= DM.SinkLimitation)
                { } //Cost of N fixation can be met by DM supply that was not allocated
                else
                {//claw back todays NonStructuralDM allocation to cover the cost
                    double UnallocatedRespirationCost = DM.TotalRespiration - DM.SinkLimitation;
                    if (DM.TotalNonStructuralAllocation > 0)
                    {
                        for (int i = 0; i < Organs.Length; i++)
                        {
                            double proportion = DM.NonStructuralAllocation[i] / DM.TotalNonStructuralAllocation;
                            double Clawback = Math.Min(UnallocatedRespirationCost * proportion, DM.NonStructuralAllocation[i]);
                            DM.NonStructuralAllocation[i] -= Clawback;
                            UnallocatedRespirationCost -= Clawback;
                        }
                    }
                    if (UnallocatedRespirationCost == 0)
                    { }//All cost accounted for
                    else
                    {//Remobilise more Non-structural DM to cover the cost
                        if (DM.TotalRetranslocationSupply > 0)
                        {
                            for (int i = 0; i < Organs.Length; i++)
                            {
                                double proportion = DM.RetranslocationSupply[i] / DM.TotalRetranslocationSupply;
                                double DMRetranslocated = Math.Min(UnallocatedRespirationCost * proportion, DM.RetranslocationSupply[i]);
                                DM.Retranslocation[i] += DMRetranslocated;
                                UnallocatedRespirationCost -= DMRetranslocated;
                            }
                        }
                        if (UnallocatedRespirationCost == 0)
                        { }//All cost accounted for
                        else
                        {//Start cutting into Structural and Metabolic Allocations
                            if ((DM.TotalStructuralAllocation + DM.TotalMetabolicAllocation) > 0)
                            {
                                double Costmet = 0;
                                for (int i = 0; i < Organs.Length; i++)
                                {
                                    if ((DM.StructuralAllocation[i] + DM.MetabolicAllocation[i]) > 0)
                                    {
                                        double proportion = (DM.StructuralAllocation[i] + DM.MetabolicAllocation[i]) / (DM.TotalStructuralAllocation + DM.TotalMetabolicAllocation);
                                        double StructualFraction = DM.StructuralAllocation[i] / (DM.StructuralAllocation[i] + DM.MetabolicAllocation[i]);
                                        double StructuralClawback = Math.Min(UnallocatedRespirationCost * proportion * StructualFraction, DM.StructuralAllocation[i]);
                                        double MetabolicClawback = Math.Min(UnallocatedRespirationCost * proportion * (1 - StructualFraction), DM.MetabolicAllocation[i]);
                                        DM.StructuralAllocation[i] -= StructuralClawback;
                                        DM.MetabolicAllocation[i] -= MetabolicClawback;
                                        Costmet += (StructuralClawback + MetabolicClawback);
                                    }
                                }
                                UnallocatedRespirationCost -= Costmet;
                            }
                        }
                        if (UnallocatedRespirationCost > 0.0000000001)
                            throw new Exception("Crop is trying to Fix excessive amounts of " + BAT.BiomassType +" Check partitioning coefficients are giving realistic nodule size and that FixationRatePotential is realistic");
                    }
                }
            }
        }
コード例 #10
0
ファイル: SvcThreadSync.cs プロジェクト: reuniware/Ryujinx
        private void SvcWaitForAddress(CpuThreadState threadState)
        {
            long            address = (long)threadState.X0;
            ArbitrationType type    = (ArbitrationType)threadState.X1;
            int             value   = (int)threadState.X2;
            long            timeout = (long)threadState.X3;

            Logger.PrintDebug(LogClass.KernelSvc,
                              "Address = 0x" + address.ToString("x16") + ", " +
                              "Type = " + type.ToString() + ", " +
                              "Value = 0x" + value.ToString("x8") + ", " +
                              "Timeout = 0x" + timeout.ToString("x16"));

            if (IsPointingInsideKernel(address))
            {
                Logger.PrintWarning(LogClass.KernelSvc, $"Invalid address 0x{address:x16}!");

                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);

                return;
            }

            if (IsAddressNotWordAligned(address))
            {
                Logger.PrintWarning(LogClass.KernelSvc, $"Unaligned address 0x{address:x16}!");

                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidAddress);

                return;
            }

            KProcess currentProcess = _system.Scheduler.GetCurrentProcess();

            long result;

            switch (type)
            {
            case ArbitrationType.WaitIfLessThan:
                result = currentProcess.AddressArbiter.WaitForAddressIfLessThan(address, value, false, timeout);
                break;

            case ArbitrationType.DecrementAndWaitIfLessThan:
                result = currentProcess.AddressArbiter.WaitForAddressIfLessThan(address, value, true, timeout);
                break;

            case ArbitrationType.WaitIfEqual:
                result = currentProcess.AddressArbiter.WaitForAddressIfEqual(address, value, timeout);
                break;

            default:
                result = MakeError(ErrorModule.Kernel, KernelErr.InvalidEnumValue);
                break;
            }

            if (result != 0)
            {
                Logger.PrintWarning(LogClass.KernelSvc, $"Operation failed with error 0x{result:x}!");
            }

            threadState.X0 = (ulong)result;
        }