Beispiel #1
0
        public NvInternalResult SignalEvent(uint eventId)
        {
            if (eventId >= EventsCount)
            {
                return(NvInternalResult.InvalidInput);
            }

            NvHostEvent hostEvent = Events[eventId];

            if (hostEvent == null)
            {
                return(NvInternalResult.InvalidInput);
            }

            NvHostEventState oldState = hostEvent.State;

            if (oldState == NvHostEventState.Waiting)
            {
                hostEvent.State = NvHostEventState.Cancelling;

                hostEvent.Cancel(_device.Gpu);
            }

            hostEvent.State = NvHostEventState.Cancelled;

            return(NvInternalResult.Success);
        }
Beispiel #2
0
        private NvInternalResult EventSignal(ref uint userEventId)
        {
            uint eventId = userEventId & ushort.MaxValue;

            if (eventId >= EventsCount)
            {
                return(NvInternalResult.InvalidInput);
            }

            lock (_events)
            {
                NvHostEvent hostEvent = _events[eventId];

                if (hostEvent == null)
                {
                    return(NvInternalResult.InvalidInput);
                }

                hostEvent.Cancel(_device.Gpu);

                _device.System.HostSyncpoint.UpdateMin(hostEvent.Fence.Id);

                return(NvInternalResult.Success);
            }
        }
Beispiel #3
0
        private NvInternalResult EventUnregister(ref uint userEventId)
        {
            lock (_events)
            {
                if (userEventId >= EventsCount)
                {
                    return(NvInternalResult.InvalidInput);
                }

                NvHostEvent hostEvent = _events[userEventId];

                if (hostEvent == null)
                {
                    return(NvInternalResult.Success);
                }

                if (hostEvent.State == NvHostEventState.Available ||
                    hostEvent.State == NvHostEventState.Cancelled ||
                    hostEvent.State == NvHostEventState.Signaled)
                {
                    _events[userEventId].CloseEvent(Context);
                    _events[userEventId] = null;

                    return(NvInternalResult.Success);
                }

                return(NvInternalResult.Busy);
            }
        }
Beispiel #4
0
        private NvInternalResult EventSignal(ref uint userEventId)
        {
            uint eventId = userEventId & ushort.MaxValue;

            if (eventId >= EventsCount)
            {
                return(NvInternalResult.InvalidInput);
            }

            NvHostEvent hostEvent = _events[eventId];

            if (hostEvent == null)
            {
                return(NvInternalResult.InvalidInput);
            }

            NvHostEventState oldState = hostEvent.State;

            if (oldState == NvHostEventState.Waiting)
            {
                hostEvent.State = NvHostEventState.Cancelling;

                hostEvent.Cancel(_device.Gpu);
            }

            hostEvent.State = NvHostEventState.Cancelled;

            return(NvInternalResult.Success);
        }
Beispiel #5
0
        public NvInternalResult RegisterEvent(uint eventId)
        {
            NvInternalResult result = UnregisterEvent(eventId);

            if (result == NvInternalResult.Success)
            {
                Events[eventId] = new NvHostEvent(this, eventId, _device.System);
            }

            return(result);
        }
Beispiel #6
0
        private NvInternalResult EventRegister(ref uint userEventId)
        {
            NvInternalResult result = EventUnregister(ref userEventId);

            if (result == NvInternalResult.Success)
            {
                _events[userEventId] = new NvHostEvent(_device.System.HostSyncpoint, userEventId, _device.System);
            }

            return(result);
        }
Beispiel #7
0
        private static NvHostEvent GetFreeEvent(
            ServiceCtx context,
            NvHostSyncpt syncpt,
            int id,
            out int eventIndex)
        {
            NvHostEvent[] events = GetUserCtx(context).Events;

            eventIndex = NvHostCtrlUserCtx.EventsCount;

            int nullIndex = NvHostCtrlUserCtx.EventsCount;

            for (int index = 0; index < NvHostCtrlUserCtx.EventsCount; index++)
            {
                NvHostEvent Event = events[index];

                if (Event != null)
                {
                    if (Event.State == NvHostEventState.Registered ||
                        Event.State == NvHostEventState.Free)
                    {
                        eventIndex = index;

                        if (Event.Id == id)
                        {
                            return(Event);
                        }
                    }
                }
                else if (nullIndex == NvHostCtrlUserCtx.EventsCount)
                {
                    nullIndex = index;
                }
            }

            if (nullIndex < NvHostCtrlUserCtx.EventsCount)
            {
                eventIndex = nullIndex;

                return(events[nullIndex] = new NvHostEvent());
            }

            if (eventIndex < NvHostCtrlUserCtx.EventsCount)
            {
                return(events[eventIndex]);
            }

            return(null);
        }
Beispiel #8
0
        public NvHostEvent GetFreeEvent(uint id, out uint eventIndex)
        {
            eventIndex = EventsCount;

            uint nullIndex = EventsCount;

            for (uint index = 0; index < EventsCount; index++)
            {
                NvHostEvent Event = Events[index];

                if (Event != null)
                {
                    if (Event.State == NvHostEventState.Availaible ||
                        Event.State == NvHostEventState.Signaled ||
                        Event.State == NvHostEventState.Cancelled)
                    {
                        eventIndex = index;

                        if (Event.Fence.Id == id)
                        {
                            return(Event);
                        }
                    }
                }
                else if (nullIndex == EventsCount)
                {
                    nullIndex = index;
                }
            }

            if (nullIndex < EventsCount)
            {
                eventIndex = nullIndex;

                RegisterEvent(eventIndex);

                return(Events[nullIndex]);
            }

            if (eventIndex < EventsCount)
            {
                return(Events[eventIndex]);
            }

            return(null);
        }
Beispiel #9
0
        public override void Close()
        {
            Logger.Warning?.Print(LogClass.ServiceNv, "Closing channel");

            lock (_events)
            {
                // If the device file need to be closed, cancel all user events and dispose events.
                for (int i = 0; i < _events.Length; i++)
                {
                    NvHostEvent evnt = _events[i];

                    if (evnt != null)
                    {
                        lock (evnt.Lock)
                        {
                            if (evnt.State == NvHostEventState.Waiting)
                            {
                                evnt.State = NvHostEventState.Cancelling;

                                evnt.Cancel(_device.Gpu);
                            }
                            else if (evnt.State == NvHostEventState.Signaling)
                            {
                                // Wait at max 9ms if the guest app is trying to signal the event while closing it..
                                int retryCount = 0;
                                do
                                {
                                    if (retryCount++ > 9)
                                    {
                                        break;
                                    }

                                    // TODO: This should be handled by the kernel (reschedule the current thread ect), waiting for Kernel decoupling work.
                                    Thread.Sleep(1);
                                } while (evnt.State != NvHostEventState.Signaled);
                            }

                            evnt.CloseEvent(Context);

                            _events[i] = null;
                        }
                    }
                }
            }
        }
Beispiel #10
0
        private NvHostEvent GetFreeEvent(int id, out int eventIndex)
        {
            eventIndex = EventsCount;

            int nullIndex = EventsCount;

            for (int index = 0; index < EventsCount; index++)
            {
                NvHostEvent Event = _events[index];

                if (Event != null)
                {
                    if (Event.State == NvHostEventState.Registered ||
                        Event.State == NvHostEventState.Free)
                    {
                        eventIndex = index;

                        if (Event.Id == id)
                        {
                            return(Event);
                        }
                    }
                }
                else if (nullIndex == EventsCount)
                {
                    nullIndex = index;
                }
            }

            if (nullIndex < EventsCount)
            {
                eventIndex = nullIndex;

                return(_events[nullIndex] = new NvHostEvent());
            }

            if (eventIndex < EventsCount)
            {
                return(_events[eventIndex]);
            }

            return(null);
        }
Beispiel #11
0
        public NvInternalResult UnregisterEvent(uint eventId)
        {
            if (eventId >= EventsCount)
            {
                return(NvInternalResult.InvalidInput);
            }

            NvHostEvent hostEvent = Events[eventId];

            if (hostEvent == null)
            {
                return(NvInternalResult.Success);
            }

            if (hostEvent.State == NvHostEventState.Availaible || hostEvent.State == NvHostEventState.Cancelled || hostEvent.State == NvHostEventState.Signaled)
            {
                Events[eventId] = null;

                return(NvInternalResult.Success);
            }

            return(NvInternalResult.Busy);
        }