示例#1
0
        public ResultCode UpdateMemoryPools(Span <MemoryPoolState> memoryPools)
        {
            PoolMapper mapper = new PoolMapper(_processHandle, _behaviourContext.IsMemoryPoolForceMappingEnabled());

            if (memoryPools.Length * Unsafe.SizeOf <MemoryPoolInParameter>() != _inputHeader.MemoryPoolsSize)
            {
                return(ResultCode.InvalidUpdateInfo);
            }

            foreach (ref MemoryPoolState memoryPool in memoryPools)
            {
                MemoryPoolInParameter parameter = SpanIOHelper.Read <MemoryPoolInParameter>(ref _input);

                ref MemoryPoolOutStatus outStatus = ref SpanIOHelper.GetWriteRef <MemoryPoolOutStatus>(ref _output)[0];

                PoolMapper.UpdateResult updateResult = mapper.Update(ref memoryPool, ref parameter, ref outStatus);

                if (updateResult != PoolMapper.UpdateResult.Success &&
                    updateResult != PoolMapper.UpdateResult.MapError &&
                    updateResult != PoolMapper.UpdateResult.UnmapError)
                {
                    if (updateResult != PoolMapper.UpdateResult.InvalidParameter)
                    {
                        throw new InvalidOperationException($"{updateResult}");
                    }

                    return(ResultCode.InvalidUpdateInfo);
                }
            }
示例#2
0
        /// <summary>
        /// Update a <see cref="MemoryPoolState"/> using user parameters.
        /// </summary>
        /// <param name="memoryPool">The <see cref="MemoryPoolState"/> to update.</param>
        /// <param name="inParameter">Input user parameter.</param>
        /// <param name="outStatus">Output user parameter.</param>
        /// <returns>Returns the <see cref="UpdateResult"/> of the operations performed.</returns>
        public UpdateResult Update(ref MemoryPoolState memoryPool, ref MemoryPoolInParameter inParameter, ref MemoryPoolOutStatus outStatus)
        {
            MemoryPoolUserState inputState = inParameter.State;

            MemoryPoolUserState outputState;

            const uint pageSize = 0x1000;

            if (inputState != MemoryPoolUserState.RequestAttach && inputState != MemoryPoolUserState.RequestDetach)
            {
                return(UpdateResult.Success);
            }

            if (inParameter.CpuAddress == 0 || (inParameter.CpuAddress & (pageSize - 1)) != 0)
            {
                return(UpdateResult.InvalidParameter);
            }

            if (inParameter.Size == 0 || (inParameter.Size & (pageSize - 1)) != 0)
            {
                return(UpdateResult.InvalidParameter);
            }

            if (inputState == MemoryPoolUserState.RequestAttach)
            {
                bool initializeSuccess = InitializePool(ref memoryPool, inParameter.CpuAddress, inParameter.Size);

                if (!initializeSuccess)
                {
                    memoryPool.SetCpuAddress(0, 0);

                    Logger.Error?.Print(LogClass.AudioRenderer, $"Map of memory pool (address: 0x{inParameter.CpuAddress:x}, size 0x{inParameter.Size:x}) failed!");
                    return(UpdateResult.MapError);
                }

                outputState = MemoryPoolUserState.Attached;
            }
            else
            {
                if (memoryPool.CpuAddress != inParameter.CpuAddress || memoryPool.Size != inParameter.Size)
                {
                    return(UpdateResult.InvalidParameter);
                }

                if (!Unmap(ref memoryPool))
                {
                    Logger.Error?.Print(LogClass.AudioRenderer, $"Unmap of memory pool (address: 0x{memoryPool.CpuAddress:x}, size 0x{memoryPool.Size:x}) failed!");
                    return(UpdateResult.UnmapError);
                }

                outputState = MemoryPoolUserState.Detached;
            }

            outStatus.State = outputState;

            return(UpdateResult.Success);
        }