diff --git a/desktop/os.header b/desktop/os.header index 1954fab..6ef1a39 100644 --- a/desktop/os.header +++ b/desktop/os.header @@ -317,8 +317,6 @@ define ES_ERROR_FILE_TOO_FRAGMENTED (-54) define ES_ERROR_DRIVE_FULL (-55) define ES_ERROR_COULD_NOT_RESOLVE_SYMBOL (-56) define ES_ERROR_ALREADY_EMBEDDED (-57) -define ES_ERROR_EVENT_SINK_OVERFLOW (-58) -define ES_ERROR_EVENT_SINK_DUPLICATE (-59) define ES_ERROR_UNSUPPORTED_CONVERSION (-60) define ES_ERROR_SOURCE_EMPTY (-61) define ES_ERROR_UNSUPPORTED_EXECUTABLE (-62) @@ -342,8 +340,6 @@ define ES_CURRENT_PROCESS ((EsHandle) (0x11)) define ES_WAIT_NO_TIMEOUT (-1) define ES_MAX_WAIT_COUNT (8) -define ES_MAX_EVENT_FORWARD_COUNT (4) // The maximum number of event sinks an event can be forwarded to. -define ES_MAX_EVENT_SINK_BUFFER_SIZE (256) // The maximum number of events an event sink can capture. TODO Make this configurable in EsEventSinkCreate? define ES_MAX_DIRECTORY_CHILD_NAME_LENGTH (256) @@ -779,12 +775,8 @@ private enum EsSyscallType { // Processing. ES_SYSCALL_EVENT_CREATE - ES_SYSCALL_EVENT_FORWARD ES_SYSCALL_EVENT_RESET ES_SYSCALL_EVENT_SET - ES_SYSCALL_EVENT_SINK_CREATE - ES_SYSCALL_EVENT_SINK_POP - ES_SYSCALL_EVENT_SINK_PUSH ES_SYSCALL_PROCESS_CRASH ES_SYSCALL_PROCESS_CREATE ES_SYSCALL_PROCESS_GET_STATE @@ -2218,14 +2210,9 @@ function size_t EsPipeWrite(EsHandle pipe, const void *buffer, size_t bytes); // Synchronisation and timing. function EsHandle EsEventCreate(bool autoReset); -function void EsEventForward(EsHandle event, EsHandle eventSink, EsGeneric data); // TODO Forwarding process/thread killed events. function void EsEventReset(EsHandle event); function void EsEventSet(EsHandle event); -function EsHandle EsEventSinkCreate(bool ignoreDuplicates); -function EsError EsEventSinkPop(EsHandle eventSink, EsGeneric *data); // Returns ES_ERROR_EVENT_NOT_SET if empty, and ES_ERROR_EVENT_SINK_OVERFLOW if data lost. -function EsError EsEventSinkPush(EsHandle eventSink, EsGeneric data); // Returns ES_ERROR_EVENT_SINK_DUPLICATE if duplicate, and ES_ERROR_EVENT_SINK_OVERFLOW if data lost. - function void EsMutexAcquire(EsMutex *mutex); function void EsMutexDestroy(EsMutex *mutex); function void EsMutexRelease(EsMutex *mutex); diff --git a/desktop/syscall.cpp b/desktop/syscall.cpp index ab9d991..78182d2 100644 --- a/desktop/syscall.cpp +++ b/desktop/syscall.cpp @@ -737,23 +737,6 @@ EsError EsConnectionRead(EsConnection *connection, void *_buffer, size_t bufferB return ES_SUCCESS; } -void EsEventForward(EsHandle event, EsHandle eventSink, EsGeneric data) { - EsSyscall(ES_SYSCALL_EVENT_FORWARD, event, eventSink, data.u, 0); -} - -EsHandle EsEventSinkCreate(bool ignoreDuplicates) { - return EsSyscall(ES_SYSCALL_EVENT_SINK_CREATE, ignoreDuplicates, 0, 0, 0); -} - -EsError EsEventSinkPop(EsHandle eventSink, EsGeneric *data) { - EsGeneric unused; if (!data) data = &unused; - return EsSyscall(ES_SYSCALL_EVENT_SINK_POP, eventSink, (uintptr_t) data, 0, 0); -} - -EsError EsEventSinkPush(EsHandle eventSink, EsGeneric data) { - return EsSyscall(ES_SYSCALL_EVENT_SINK_PUSH, eventSink, data.u, 0, 0); -} - size_t EsGameControllerStatePoll(EsGameControllerState *buffer) { return EsSyscall(ES_SYSCALL_GAME_CONTROLLER_STATE_POLL, (uintptr_t) buffer, 0, 0, 0); } diff --git a/kernel/module.h b/kernel/module.h index e4e1600..461380b 100644 --- a/kernel/module.h +++ b/kernel/module.h @@ -190,7 +190,6 @@ enum KernelObjectType : uint32_t { #endif KERNEL_OBJECT_PIPE = 0x00000200, // A pipe through which data can be sent between processes, blocking when full or empty. KERNEL_OBJECT_EMBEDDED_WINDOW = 0x00000400, // An embedded window object, referencing its container Window. - KERNEL_OBJECT_EVENT_SINK = 0x00002000, // An event sink. Events can be forwarded to it, allowing waiting on many objects. KERNEL_OBJECT_CONNECTION = 0x00004000, // A network connection. KERNEL_OBJECT_DEVICE = 0x00008000, // A device. }; @@ -267,15 +266,11 @@ void KMutexRelease(KMutex *mutex); void KMutexAssertLocked(KMutex *mutex); struct KEvent { // Waiting and notifying. Can wait on multiple at once. Can be set and reset with interrupts disabled. - volatile bool autoReset; // This should be first field in the structure, - // so that the type of KEvent can be easily declared with {autoReset}. + volatile bool autoReset; // This should be first field in the structure, so that the type of KEvent can be easily declared with {autoReset}. volatile uintptr_t state; - K_PRIVATE - LinkedList blockedThreads; volatile size_t handles; - struct EventSinkTable *sinkTable; }; bool KEventSet(KEvent *event, bool schedulerAlreadyLocked = false, bool maybeAlreadySet = false); diff --git a/kernel/objects.cpp b/kernel/objects.cpp index b00d16d..5be0e58 100644 --- a/kernel/objects.cpp +++ b/kernel/objects.cpp @@ -34,23 +34,6 @@ struct Pipe { size_t Access(void *buffer, size_t bytes, bool write, bool userBlockRequest); }; -struct EventSink { - KEvent available; - KSpinlock spinlock; // Take after the scheduler's spinlock. - volatile size_t handles; - uintptr_t queuePosition; - size_t queueCount; - bool overflow, ignoreDuplicates; - EsGeneric queue[ES_MAX_EVENT_SINK_BUFFER_SIZE]; - - EsError Push(EsGeneric data); -}; - -struct EventSinkTable { - EventSink *sink; - EsGeneric data; -}; - struct MessageQueue { bool SendMessage(void *target, EsMessage *message); // Returns false if the message queue is full. bool SendMessage(_EsMessageWithObject *message); // Returns false if the message queue is full. @@ -210,14 +193,6 @@ bool OpenHandleToObject(void *object, KernelObjectType type, uint32_t flags, boo KMutexRelease(&pipe->mutex); } break; - case KERNEL_OBJECT_EVENT_SINK: { - EventSink *sink = (EventSink *) object; - KSpinlockAcquire(&sink->spinlock); - if (!sink->handles) hadNoHandles = true; - else sink->handles++; - KSpinlockRelease(&sink->spinlock); - } break; - case KERNEL_OBJECT_CONNECTION: { NetConnection *connection = (NetConnection *) object; hadNoHandles = 0 == __sync_fetch_and_add(&connection->handles, 1); @@ -275,16 +250,6 @@ void CloseHandleToObject(void *object, KernelObjectType type, uint32_t flags) { KMutexRelease(&objectHandleCountChange); if (destroy) { - if (event->sinkTable) { - for (uintptr_t i = 0; i < ES_MAX_EVENT_FORWARD_COUNT; i++) { - if (event->sinkTable[i].sink) { - CloseHandleToObject(event->sinkTable[i].sink, KERNEL_OBJECT_EVENT_SINK, 0); - } - } - - EsHeapFree(event->sinkTable, sizeof(EventSinkTable) * ES_MAX_EVENT_FORWARD_COUNT, K_FIXED); - } - EsHeapFree(event, sizeof(KEvent), K_FIXED); } } break; @@ -386,18 +351,6 @@ void CloseHandleToObject(void *object, KernelObjectType type, uint32_t flags) { } } break; - case KERNEL_OBJECT_EVENT_SINK: { - EventSink *sink = (EventSink *) object; - KSpinlockAcquire(&sink->spinlock); - bool destroy = sink->handles == 1; - sink->handles--; - KSpinlockRelease(&sink->spinlock); - - if (destroy) { - EsHeapFree(sink, sizeof(EventSink), K_FIXED); - } - } break; - case KERNEL_OBJECT_CONNECTION: { NetConnection *connection = (NetConnection *) object; unsigned previous = __sync_fetch_and_sub(&connection->handles, 1); diff --git a/kernel/synchronisation.cpp b/kernel/synchronisation.cpp index f2ef8d4..19889d9 100644 --- a/kernel/synchronisation.cpp +++ b/kernel/synchronisation.cpp @@ -314,55 +314,6 @@ void KSemaphoreSet(KSemaphore *semaphore, uintptr_t u) { KMutexRelease(&semaphore->mutex); } -EsError EventSink::Push(EsGeneric data) { - EsError result = ES_SUCCESS; - - KSpinlockAssertLocked(&scheduler.lock); - - KSpinlockAcquire(&spinlock); - - if (queueCount == ES_MAX_EVENT_SINK_BUFFER_SIZE) { - overflow = true; - result = ES_ERROR_EVENT_SINK_OVERFLOW; - KernelLog(LOG_VERBOSE, "Event Sinks", "push overflow", "Push %d into %x.\n", data.i, this); - } else { - bool ignored = false; - - if (ignoreDuplicates) { - uintptr_t index = queuePosition; - - for (uintptr_t i = 0; i < queueCount; i++) { - if (queue[index] == data) { - ignored = true; - result = ES_ERROR_EVENT_SINK_DUPLICATE; - KernelLog(LOG_VERBOSE, "Event Sinks", "push ignored", "Push %d into %x.\n", data.i, this); - break; - } - - index++; - - if (index == ES_MAX_EVENT_SINK_BUFFER_SIZE) { - index = 0; - } - } - } - - if (!ignored) { - uintptr_t writeIndex = queuePosition + queueCount; - if (writeIndex >= ES_MAX_EVENT_SINK_BUFFER_SIZE) writeIndex -= ES_MAX_EVENT_SINK_BUFFER_SIZE; - if (writeIndex >= ES_MAX_EVENT_SINK_BUFFER_SIZE) KernelPanic("EventSink::Push - Invalid event sink (%x) queue.\n", this); - KernelLog(LOG_VERBOSE, "Event Sinks", "push", "Push %d into %x at %d (%d/%d).\n", data.i, this, writeIndex, queuePosition, queueCount); - queue[writeIndex] = data; - queueCount++; - KEventSet(&available, true, true); - } - } - - KSpinlockRelease(&spinlock); - - return result; -} - bool KEventSet(KEvent *event, bool schedulerAlreadyLocked, bool maybeAlreadySet) { if (event->state && !maybeAlreadySet) { KernelLog(LOG_ERROR, "Synchronisation", "event already set", "KEvent::Set - Attempt to set a event that had already been set\n"); @@ -377,13 +328,6 @@ bool KEventSet(KEvent *event, bool schedulerAlreadyLocked, bool maybeAlreadySet) volatile bool unblockedThreads = false; if (!event->state) { - if (event->sinkTable) { - for (uintptr_t i = 0; i < ES_MAX_EVENT_FORWARD_COUNT; i++) { - if (!event->sinkTable[i].sink) continue; - event->sinkTable[i].sink->Push(event->sinkTable[i].data); - } - } - event->state = true; if (scheduler.started) { diff --git a/kernel/syscall.cpp b/kernel/syscall.cpp index 4e32edb..9e0d002 100644 --- a/kernel/syscall.cpp +++ b/kernel/syscall.cpp @@ -806,7 +806,7 @@ SYSCALL_IMPLEMENT(ES_SYSCALL_WAIT) { SYSCALL_READ(handles, argument0, argument1 * sizeof(EsHandle)); for (uintptr_t i = 0; i < argument1; i++) { - KernelObjectType typeMask = KERNEL_OBJECT_PROCESS | KERNEL_OBJECT_THREAD | KERNEL_OBJECT_EVENT | KERNEL_OBJECT_EVENT_SINK; + KernelObjectType typeMask = KERNEL_OBJECT_PROCESS | KERNEL_OBJECT_THREAD | KERNEL_OBJECT_EVENT; status[i] = currentProcess->handleTable.ResolveHandle(&_objects[i], handles[i], typeMask); if (status[i] == RESOLVE_HANDLE_FAILED) { @@ -825,10 +825,6 @@ SYSCALL_IMPLEMENT(ES_SYSCALL_WAIT) { events[i] = &((Thread *) object)->killedEvent; } break; - case KERNEL_OBJECT_EVENT_SINK: { - events[i] = &((EventSink *) object)->available; - } break; - case KERNEL_OBJECT_EVENT: { events[i] = (KEvent *) object; } break; @@ -1464,111 +1460,6 @@ SYSCALL_IMPLEMENT(ES_SYSCALL_PIPE_WRITE) { SYSCALL_RETURN(pipe->Access((void *) argument1, argument2, true, true), false); } -SYSCALL_IMPLEMENT(ES_SYSCALL_EVENT_SINK_CREATE) { - EventSink *sink = (EventSink *) EsHeapAllocate(sizeof(EventSink), true, K_FIXED); - - if (!sink) { - SYSCALL_RETURN(ES_ERROR_INSUFFICIENT_RESOURCES, false); - } - - sink->ignoreDuplicates = argument0; - sink->handles = 1; - - SYSCALL_RETURN(currentProcess->handleTable.OpenHandle(sink, 0, KERNEL_OBJECT_EVENT_SINK), false); -} - -SYSCALL_IMPLEMENT(ES_SYSCALL_EVENT_FORWARD) { - SYSCALL_HANDLE(argument0, KERNEL_OBJECT_EVENT, event, KEvent); - SYSCALL_HANDLE(argument1, KERNEL_OBJECT_EVENT_SINK, sink, EventSink); - EsGeneric data = argument2; - - bool error = false, limitExceeded = false; - - KMutexAcquire(&eventForwardMutex); - - if (!event->sinkTable) { - event->sinkTable = (EventSinkTable *) EsHeapAllocate(sizeof(EventSinkTable) * ES_MAX_EVENT_FORWARD_COUNT, true, K_FIXED); - - if (!event->sinkTable) { - error = true; - } - } - - if (!error) { - limitExceeded = true; - - for (uintptr_t i = 0; i < ES_MAX_EVENT_FORWARD_COUNT; i++) { - if (!event->sinkTable[i].sink) { - if (!OpenHandleToObject(sink, KERNEL_OBJECT_EVENT_SINK, 0, false)) { - error = true; - break; - } - - KSpinlockAcquire(&scheduler.lock); - event->sinkTable[i].sink = sink; - event->sinkTable[i].data = data; - KSpinlockRelease(&scheduler.lock); - - limitExceeded = false; - break; - } - } - } - - KMutexRelease(&eventForwardMutex); - - if (limitExceeded) { - SYSCALL_RETURN(ES_FATAL_ERROR_OUT_OF_RANGE, true); - } else if (error) { - SYSCALL_RETURN(ES_ERROR_INSUFFICIENT_RESOURCES, false); - } else { - SYSCALL_RETURN(0, false); - } -} - -SYSCALL_IMPLEMENT(ES_SYSCALL_EVENT_SINK_POP) { - SYSCALL_HANDLE(argument0, KERNEL_OBJECT_EVENT_SINK, sink, EventSink); - - bool empty = false, overflow = false; - EsGeneric data = {}; - - KSpinlockAcquire(&sink->spinlock); - - if (!sink->queueCount) { - if (sink->overflow) { - overflow = true; - sink->overflow = false; - } else { - empty = true; - } - } else { - data = sink->queue[sink->queuePosition]; - sink->queuePosition++; - sink->queueCount--; - - if (sink->queuePosition == ES_MAX_EVENT_SINK_BUFFER_SIZE) { - sink->queuePosition = 0; - } - } - - if (!sink->queueCount && !sink->overflow) { - KEventReset(&sink->available); // KEvent::Reset doesn't take the scheduler lock, so this won't deadlock! - } - - KSpinlockRelease(&sink->spinlock); - - SYSCALL_WRITE(argument1, &data, sizeof(EsGeneric)); - SYSCALL_RETURN(overflow ? ES_ERROR_EVENT_SINK_OVERFLOW : empty ? ES_ERROR_EVENT_NOT_SET : ES_SUCCESS, false); -} - -SYSCALL_IMPLEMENT(ES_SYSCALL_EVENT_SINK_PUSH) { - SYSCALL_HANDLE(argument0, KERNEL_OBJECT_EVENT_SINK, sink, EventSink); - KSpinlockAcquire(&scheduler.lock); - EsError result = sink->Push(argument1); - KSpinlockRelease(&scheduler.lock); - SYSCALL_RETURN(result, false); -} - SYSCALL_IMPLEMENT(ES_SYSCALL_DOMAIN_NAME_RESOLVE) { SYSCALL_PERMISSION(ES_PERMISSION_NETWORKING); diff --git a/util/api_table.ini b/util/api_table.ini index 5f52703..5ad7a8c 100644 --- a/util/api_table.ini +++ b/util/api_table.ini @@ -131,13 +131,9 @@ EsPipeRead=129 EsListViewInsert=130 EsListViewRemove=131 EsEventCreate=132 -EsEventForward=133 EsBufferFormat=134 EsEventReset=135 EsEventSet=136 -EsEventSinkCreate=137 -EsEventSinkPop=138 -EsEventSinkPush=139 EsMutexAcquire=140 EsMutexDestroy=141 EsMutexRelease=142