mirror of https://gitlab.com/nakst/essence
simplify KEventSet
This commit is contained in:
parent
85909972dc
commit
97ae44396b
|
@ -364,7 +364,7 @@ bool AHCIController::HandleIRQ() {
|
||||||
}
|
}
|
||||||
|
|
||||||
port->runningCommands = 0;
|
port->runningCommands = 0;
|
||||||
KEventSet(&port->commandSlotsAvailable, false, true /* maybe already set */);
|
KEventSet(&port->commandSlotsAvailable, true /* maybe already set */);
|
||||||
|
|
||||||
// Restart command processing.
|
// Restart command processing.
|
||||||
|
|
||||||
|
@ -392,7 +392,7 @@ bool AHCIController::HandleIRQ() {
|
||||||
|
|
||||||
port->commandContexts[j]->End(true /* success */);
|
port->commandContexts[j]->End(true /* success */);
|
||||||
port->commandContexts[j] = nullptr;
|
port->commandContexts[j] = nullptr;
|
||||||
KEventSet(&port->commandSlotsAvailable, false, true /* maybe already set */);
|
KEventSet(&port->commandSlotsAvailable, true /* maybe already set */);
|
||||||
port->runningCommands &= ~(1 << j);
|
port->runningCommands &= ~(1 << j);
|
||||||
|
|
||||||
commandCompleted = true;
|
commandCompleted = true;
|
||||||
|
|
|
@ -280,7 +280,7 @@ bool Controller::HandleIRQ() {
|
||||||
if (cause & (1 << 2)) {
|
if (cause & (1 << 2)) {
|
||||||
KernelLog(LOG_INFO, "I8254x", "link status change", "Link is now %z.\n",
|
KernelLog(LOG_INFO, "I8254x", "link status change", "Link is now %z.\n",
|
||||||
(RD_REGISTER_STATUS() & (1 << 1)) ? "up" : "down");
|
(RD_REGISTER_STATUS() & (1 << 1)) ? "up" : "down");
|
||||||
KEventSet(&receiveEvent, false, true);
|
KEventSet(&receiveEvent, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cause & (1 << 6)) {
|
if (cause & (1 << 6)) {
|
||||||
|
@ -288,7 +288,7 @@ bool Controller::HandleIRQ() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cause & ((1 << 6) | (1 << 7) | (1 << 4))) {
|
if (cause & ((1 << 6) | (1 << 7) | (1 << 4))) {
|
||||||
KEventSet(&receiveEvent, false, true);
|
KEventSet(&receiveEvent, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -433,7 +433,7 @@ bool NVMeController::HandleIRQ() {
|
||||||
|
|
||||||
__sync_synchronize();
|
__sync_synchronize();
|
||||||
ioSubmissionQueueHead = *(uint16_t *) (ioCompletionQueue + ioCompletionQueueHead * COMPLETION_QUEUE_ENTRY_BYTES + 8);
|
ioSubmissionQueueHead = *(uint16_t *) (ioCompletionQueue + ioCompletionQueueHead * COMPLETION_QUEUE_ENTRY_BYTES + 8);
|
||||||
KEventSet(&ioSubmissionQueueNonFull, false, true);
|
KEventSet(&ioSubmissionQueueNonFull, true);
|
||||||
|
|
||||||
// Advance the queue head.
|
// Advance the queue head.
|
||||||
|
|
||||||
|
|
|
@ -685,7 +685,7 @@ bool XHCIController::HandleIRQ() {
|
||||||
KernelLog(LOG_INFO, "xHCI", "port enabled", "Port %d has been enabled.\n", port);
|
KernelLog(LOG_INFO, "xHCI", "port enabled", "Port %d has been enabled.\n", port);
|
||||||
ports[port].statusChangeEvent = true;
|
ports[port].statusChangeEvent = true;
|
||||||
ports[port].enabled = true;
|
ports[port].enabled = true;
|
||||||
KEventSet(&portStatusChangeEvent, false, true);
|
KEventSet(&portStatusChangeEvent, true);
|
||||||
} else if (ports[port].usb2 && (linkState == 7 || linkState == 4) && (~status & (1 << 4))) {
|
} else if (ports[port].usb2 && (linkState == 7 || linkState == 4) && (~status & (1 << 4))) {
|
||||||
KernelLog(LOG_INFO, "xHCI", "port reset", "Attempting to reset USB 2 port %d... (1)\n", port);
|
KernelLog(LOG_INFO, "xHCI", "port reset", "Attempting to reset USB 2 port %d... (1)\n", port);
|
||||||
WR_REGISTER_PORTSC(port, (status & (1 << 9)) | (1 << 4));
|
WR_REGISTER_PORTSC(port, (status & (1 << 9)) | (1 << 4));
|
||||||
|
@ -693,7 +693,7 @@ bool XHCIController::HandleIRQ() {
|
||||||
KernelLog(LOG_INFO, "xHCI", "port detach", "Device detached from port %d.\n", port);
|
KernelLog(LOG_INFO, "xHCI", "port detach", "Device detached from port %d.\n", port);
|
||||||
ports[port].statusChangeEvent = true;
|
ports[port].statusChangeEvent = true;
|
||||||
ports[port].enabled = false;
|
ports[port].enabled = false;
|
||||||
KEventSet(&portStatusChangeEvent, false, true);
|
KEventSet(&portStatusChangeEvent, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
KSpinlockRelease(&portResetSpinlock);
|
KSpinlockRelease(&portResetSpinlock);
|
||||||
|
|
|
@ -247,7 +247,7 @@ void CCWriteSectionPrepare(CCActiveSection *section) {
|
||||||
section->accessors = 1;
|
section->accessors = 1;
|
||||||
if (!activeSectionManager.modifiedList.count) KEventReset(&activeSectionManager.modifiedNonEmpty);
|
if (!activeSectionManager.modifiedList.count) KEventReset(&activeSectionManager.modifiedNonEmpty);
|
||||||
if (activeSectionManager.modifiedList.count < CC_MODIFIED_GETTING_FULL) KEventReset(&activeSectionManager.modifiedGettingFull);
|
if (activeSectionManager.modifiedList.count < CC_MODIFIED_GETTING_FULL) KEventReset(&activeSectionManager.modifiedGettingFull);
|
||||||
KEventSet(&activeSectionManager.modifiedNonFull, false, true);
|
KEventSet(&activeSectionManager.modifiedNonFull, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCWriteSection(CCActiveSection *section) {
|
void CCWriteSection(CCActiveSection *section) {
|
||||||
|
@ -286,7 +286,7 @@ void CCWriteSection(CCActiveSection *section) {
|
||||||
EsMemoryZero(section->modifiedPages, sizeof(section->modifiedPages));
|
EsMemoryZero(section->modifiedPages, sizeof(section->modifiedPages));
|
||||||
__sync_synchronize();
|
__sync_synchronize();
|
||||||
KEventSet(§ion->writeCompleteEvent);
|
KEventSet(§ion->writeCompleteEvent);
|
||||||
KEventSet(§ion->cache->writeComplete, false, true);
|
KEventSet(§ion->cache->writeComplete, true);
|
||||||
|
|
||||||
if (!section->accessors) {
|
if (!section->accessors) {
|
||||||
if (section->loading) KernelPanic("CCSpaceAccess - Active section %x with no accessors is loading.", section);
|
if (section->loading) KernelPanic("CCSpaceAccess - Active section %x with no accessors is loading.", section);
|
||||||
|
@ -378,10 +378,10 @@ void CCActiveSectionReturnToLists(CCActiveSection *section, bool writeBack) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (activeSectionManager.modifiedList.count >= CC_MODIFIED_GETTING_FULL) {
|
if (activeSectionManager.modifiedList.count >= CC_MODIFIED_GETTING_FULL) {
|
||||||
KEventSet(&activeSectionManager.modifiedGettingFull, false, true);
|
KEventSet(&activeSectionManager.modifiedGettingFull, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
KEventSet(&activeSectionManager.modifiedNonEmpty, false, true);
|
KEventSet(&activeSectionManager.modifiedNonEmpty, true);
|
||||||
|
|
||||||
activeSectionManager.modifiedList.InsertEnd(§ion->listItem);
|
activeSectionManager.modifiedList.InsertEnd(§ion->listItem);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1023,7 +1023,7 @@ void FSUnmountFileSystem(uintptr_t argument) {
|
||||||
KernelLog(LOG_INFO, "FS", "unmount complete", "Unmounted file system %x.\n", fileSystem);
|
KernelLog(LOG_INFO, "FS", "unmount complete", "Unmounted file system %x.\n", fileSystem);
|
||||||
KDeviceCloseHandle(fileSystem);
|
KDeviceCloseHandle(fileSystem);
|
||||||
__sync_fetch_and_sub(&fs.fileSystemsUnmounting, 1);
|
__sync_fetch_and_sub(&fs.fileSystemsUnmounting, 1);
|
||||||
KEventSet(&fs.fileSystemUnmounted, false, true);
|
KEventSet(&fs.fileSystemUnmounted, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////
|
//////////////////////////////////////////
|
||||||
|
|
|
@ -312,11 +312,11 @@ GlobalData *globalData; // Shared with all processes.
|
||||||
|
|
||||||
void MMUpdateAvailablePageCount(bool increase) {
|
void MMUpdateAvailablePageCount(bool increase) {
|
||||||
if (MM_AVAILABLE_PAGES() >= MM_CRITICAL_AVAILABLE_PAGES_THRESHOLD) {
|
if (MM_AVAILABLE_PAGES() >= MM_CRITICAL_AVAILABLE_PAGES_THRESHOLD) {
|
||||||
KEventSet(&pmm.availableNotCritical, false, true);
|
KEventSet(&pmm.availableNotCritical, true);
|
||||||
KEventReset(&pmm.availableCritical);
|
KEventReset(&pmm.availableCritical);
|
||||||
} else {
|
} else {
|
||||||
KEventReset(&pmm.availableNotCritical);
|
KEventReset(&pmm.availableNotCritical);
|
||||||
KEventSet(&pmm.availableCritical, false, true);
|
KEventSet(&pmm.availableCritical, true);
|
||||||
|
|
||||||
if (!increase) {
|
if (!increase) {
|
||||||
KernelLog(LOG_ERROR, "Memory", "critical page limit hit",
|
KernelLog(LOG_ERROR, "Memory", "critical page limit hit",
|
||||||
|
@ -327,7 +327,7 @@ void MMUpdateAvailablePageCount(bool increase) {
|
||||||
if (MM_AVAILABLE_PAGES() >= MM_LOW_AVAILABLE_PAGES_THRESHOLD) {
|
if (MM_AVAILABLE_PAGES() >= MM_LOW_AVAILABLE_PAGES_THRESHOLD) {
|
||||||
KEventReset(&pmm.availableLow);
|
KEventReset(&pmm.availableLow);
|
||||||
} else {
|
} else {
|
||||||
KEventSet(&pmm.availableLow, false, true);
|
KEventSet(&pmm.availableLow, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -372,7 +372,7 @@ void MMPhysicalInsertFreePagesNext(uintptr_t page) {
|
||||||
|
|
||||||
void MMPhysicalInsertFreePagesEnd() {
|
void MMPhysicalInsertFreePagesEnd() {
|
||||||
if (pmm.countFreePages > MM_ZERO_PAGE_THRESHOLD) {
|
if (pmm.countFreePages > MM_ZERO_PAGE_THRESHOLD) {
|
||||||
KEventSet(&pmm.zeroPageEvent, false, true);
|
KEventSet(&pmm.zeroPageEvent, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
MMUpdateAvailablePageCount(true);
|
MMUpdateAvailablePageCount(true);
|
||||||
|
@ -1183,7 +1183,7 @@ bool MMCommit(uint64_t bytes, bool fixed) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MM_OBJECT_CACHE_SHOULD_TRIM()) {
|
if (MM_OBJECT_CACHE_SHOULD_TRIM()) {
|
||||||
KEventSet(&pmm.trimObjectCaches, false, true);
|
KEventSet(&pmm.trimObjectCaches, true);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// We haven't started tracking commit counts yet.
|
// We haven't started tracking commit counts yet.
|
||||||
|
@ -2094,7 +2094,7 @@ void MMObjectCacheInsert(MMObjectCache *cache, MMObjectCacheItem *item) {
|
||||||
__sync_fetch_and_add(&pmm.approximateTotalObjectCacheBytes, cache->averageObjectBytes);
|
__sync_fetch_and_add(&pmm.approximateTotalObjectCacheBytes, cache->averageObjectBytes);
|
||||||
|
|
||||||
if (MM_OBJECT_CACHE_SHOULD_TRIM()) {
|
if (MM_OBJECT_CACHE_SHOULD_TRIM()) {
|
||||||
KEventSet(&pmm.trimObjectCaches, false, true);
|
KEventSet(&pmm.trimObjectCaches, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
KSpinlockRelease(&cache->lock);
|
KSpinlockRelease(&cache->lock);
|
||||||
|
|
|
@ -273,7 +273,7 @@ struct KEvent { // Waiting and notifying. Can wait on multiple at once. Can be s
|
||||||
volatile size_t handles;
|
volatile size_t handles;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool KEventSet(KEvent *event, bool schedulerAlreadyLocked = false, bool maybeAlreadySet = false);
|
bool KEventSet(KEvent *event, bool maybeAlreadySet = false);
|
||||||
void KEventReset(KEvent *event);
|
void KEventReset(KEvent *event);
|
||||||
bool KEventPoll(KEvent *event); // TODO Remove this! Currently it is only used by KAudioFillBuffersFromMixer.
|
bool KEventPoll(KEvent *event); // TODO Remove this! Currently it is only used by KAudioFillBuffersFromMixer.
|
||||||
bool KEventWait(KEvent *event, uint64_t timeoutMs = ES_WAIT_NO_TIMEOUT); // See KWaitEvents to wait for multiple events. Returns false if the wait timed out.
|
bool KEventWait(KEvent *event, uint64_t timeoutMs = ES_WAIT_NO_TIMEOUT); // See KWaitEvents to wait for multiple events. Returns false if the wait timed out.
|
||||||
|
|
|
@ -276,7 +276,7 @@ void CloseHandleToObject(void *object, KernelObjectType type, uint32_t flags) {
|
||||||
if (!previous) KernelPanic("CloseHandleToObject - Window %x has no handles.\n", window);
|
if (!previous) KernelPanic("CloseHandleToObject - Window %x has no handles.\n", window);
|
||||||
|
|
||||||
if (previous == 2) {
|
if (previous == 2) {
|
||||||
KEventSet(&windowManager.windowsToCloseEvent, false, true /* maybe already set */);
|
KEventSet(&windowManager.windowsToCloseEvent, true /* maybe already set */);
|
||||||
} else if (previous == 1) {
|
} else if (previous == 1) {
|
||||||
window->Destroy();
|
window->Destroy();
|
||||||
}
|
}
|
||||||
|
@ -288,7 +288,7 @@ void CloseHandleToObject(void *object, KernelObjectType type, uint32_t flags) {
|
||||||
if (!previous) KernelPanic("CloseHandleToObject - EmbeddedWindow %x has no handles.\n", window);
|
if (!previous) KernelPanic("CloseHandleToObject - EmbeddedWindow %x has no handles.\n", window);
|
||||||
|
|
||||||
if (previous == 2) {
|
if (previous == 2) {
|
||||||
KEventSet(&windowManager.windowsToCloseEvent, false, true /* maybe already set */);
|
KEventSet(&windowManager.windowsToCloseEvent, true /* maybe already set */);
|
||||||
} else if (previous == 1) {
|
} else if (previous == 1) {
|
||||||
window->Destroy();
|
window->Destroy();
|
||||||
}
|
}
|
||||||
|
@ -321,7 +321,7 @@ void CloseHandleToObject(void *object, KernelObjectType type, uint32_t flags) {
|
||||||
|
|
||||||
if (!pipe->readers) {
|
if (!pipe->readers) {
|
||||||
// If there are no more readers, wake up any blocking writers.
|
// If there are no more readers, wake up any blocking writers.
|
||||||
KEventSet(&pipe->canWrite, false, true);
|
KEventSet(&pipe->canWrite, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -330,7 +330,7 @@ void CloseHandleToObject(void *object, KernelObjectType type, uint32_t flags) {
|
||||||
|
|
||||||
if (!pipe->writers) {
|
if (!pipe->writers) {
|
||||||
// If there are no more writers, wake up any blocking readers.
|
// If there are no more writers, wake up any blocking readers.
|
||||||
KEventSet(&pipe->canRead, false, true);
|
KEventSet(&pipe->canRead, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -621,7 +621,7 @@ size_t Pipe::Access(void *_buffer, size_t bytes, bool write, bool user) {
|
||||||
_buffer = (uint8_t *) _buffer + toWrite;
|
_buffer = (uint8_t *) _buffer + toWrite;
|
||||||
amount += toWrite;
|
amount += toWrite;
|
||||||
|
|
||||||
KEventSet(&canRead, false, true);
|
KEventSet(&canRead, true);
|
||||||
|
|
||||||
if (!readers) {
|
if (!readers) {
|
||||||
// EsPrint("\tPipe closed\n");
|
// EsPrint("\tPipe closed\n");
|
||||||
|
@ -654,7 +654,7 @@ size_t Pipe::Access(void *_buffer, size_t bytes, bool write, bool user) {
|
||||||
_buffer = (uint8_t *) _buffer + toRead;
|
_buffer = (uint8_t *) _buffer + toRead;
|
||||||
amount += toRead;
|
amount += toRead;
|
||||||
|
|
||||||
KEventSet(&canWrite, false, true);
|
KEventSet(&canWrite, true);
|
||||||
|
|
||||||
if (!writers) {
|
if (!writers) {
|
||||||
// Nobody is writing to the pipe, so there's no point reading from it.
|
// Nobody is writing to the pipe, so there's no point reading from it.
|
||||||
|
@ -724,7 +724,7 @@ bool MessageQueue::SendMessage(_EsMessageWithObject *_message) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
KEventSet(¬Empty, false, true);
|
KEventSet(¬Empty, true);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -520,14 +520,10 @@ namespace POSIX {
|
||||||
}
|
}
|
||||||
|
|
||||||
KSpinlockAcquire(&scheduler.dispatchSpinlock);
|
KSpinlockAcquire(&scheduler.dispatchSpinlock);
|
||||||
|
|
||||||
process->posixForking = false;
|
process->posixForking = false;
|
||||||
|
bool setKilledEvent = process->allThreadsTerminated;
|
||||||
if (process->allThreadsTerminated) {
|
|
||||||
KEventSet(&process->killedEvent, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
KSpinlockRelease(&scheduler.dispatchSpinlock);
|
KSpinlockRelease(&scheduler.dispatchSpinlock);
|
||||||
|
if (setKilledEvent) KEventSet(&process->killedEvent, true);
|
||||||
|
|
||||||
EsHeapFree(path, 0, K_FIXED);
|
EsHeapFree(path, 0, K_FIXED);
|
||||||
CloseHandleToObject(process->executableMainThread, KERNEL_OBJECT_THREAD);
|
CloseHandleToObject(process->executableMainThread, KERNEL_OBJECT_THREAD);
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
// TODO Review vforking interaction from the POSIX subsystem with the process termination algorithm.
|
||||||
|
// TODO Simplify or remove asynchronous task thread semantics.
|
||||||
|
// TODO Break up or remove dispatchSpinlock.
|
||||||
|
|
||||||
#ifndef IMPLEMENTATION
|
#ifndef IMPLEMENTATION
|
||||||
|
|
||||||
#define THREAD_PRIORITY_NORMAL (0) // Lower value = higher priority.
|
#define THREAD_PRIORITY_NORMAL (0) // Lower value = higher priority.
|
||||||
|
@ -523,9 +527,7 @@ void KillProcess(Process *process) {
|
||||||
KMutexRelease(&scheduler.allProcessesMutex);
|
KMutexRelease(&scheduler.allProcessesMutex);
|
||||||
|
|
||||||
KSpinlockAcquire(&scheduler.dispatchSpinlock);
|
KSpinlockAcquire(&scheduler.dispatchSpinlock);
|
||||||
|
|
||||||
process->allThreadsTerminated = true;
|
process->allThreadsTerminated = true;
|
||||||
|
|
||||||
bool setProcessKilledEvent = true;
|
bool setProcessKilledEvent = true;
|
||||||
|
|
||||||
#ifdef ENABLE_POSIX_SUBSYSTEM
|
#ifdef ENABLE_POSIX_SUBSYSTEM
|
||||||
|
@ -537,13 +539,13 @@ void KillProcess(Process *process) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
KSpinlockRelease(&scheduler.dispatchSpinlock);
|
||||||
|
|
||||||
if (setProcessKilledEvent) {
|
if (setProcessKilledEvent) {
|
||||||
// We can now also set the killed event on the process.
|
// We can now also set the killed event on the process.
|
||||||
KEventSet(&process->killedEvent, true);
|
KEventSet(&process->killedEvent, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
KSpinlockRelease(&scheduler.dispatchSpinlock);
|
|
||||||
|
|
||||||
// There are no threads left in this process.
|
// There are no threads left in this process.
|
||||||
// We should destroy the handle table at this point.
|
// We should destroy the handle table at this point.
|
||||||
// Otherwise, the process might never be freed
|
// Otherwise, the process might never be freed
|
||||||
|
@ -1152,6 +1154,36 @@ void Scheduler::Yield(InterruptContext *context) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!local->processorID) {
|
||||||
|
// Update the scheduler's time.
|
||||||
|
timeMs = ArchGetTimeMs();
|
||||||
|
globalData->schedulerTimeMs = timeMs;
|
||||||
|
|
||||||
|
// Notify the necessary timers.
|
||||||
|
KSpinlockAcquire(&activeTimersSpinlock);
|
||||||
|
LinkedItem<KTimer> *_timer = activeTimers.firstItem;
|
||||||
|
|
||||||
|
while (_timer) {
|
||||||
|
KTimer *timer = _timer->thisItem;
|
||||||
|
LinkedItem<KTimer> *next = _timer->nextItem;
|
||||||
|
|
||||||
|
if (timer->triggerTimeMs <= timeMs) {
|
||||||
|
activeTimers.Remove(_timer);
|
||||||
|
KEventSet(&timer->event);
|
||||||
|
|
||||||
|
if (timer->callback) {
|
||||||
|
KRegisterAsyncTask(&timer->asyncTask, timer->callback);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break; // Timers are kept sorted, so there's no point continuing.
|
||||||
|
}
|
||||||
|
|
||||||
|
_timer = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
KSpinlockRelease(&activeTimersSpinlock);
|
||||||
|
}
|
||||||
|
|
||||||
if (local->spinlockCount) {
|
if (local->spinlockCount) {
|
||||||
KernelPanic("Scheduler::Yield - Spinlocks acquired while attempting to yield.\n");
|
KernelPanic("Scheduler::Yield - Spinlocks acquired while attempting to yield.\n");
|
||||||
}
|
}
|
||||||
|
@ -1238,36 +1270,6 @@ void Scheduler::Yield(InterruptContext *context) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!local->processorID) {
|
|
||||||
// Update the scheduler's time.
|
|
||||||
timeMs = ArchGetTimeMs();
|
|
||||||
globalData->schedulerTimeMs = timeMs;
|
|
||||||
|
|
||||||
// Notify the necessary timers.
|
|
||||||
KSpinlockAcquire(&activeTimersSpinlock);
|
|
||||||
LinkedItem<KTimer> *_timer = activeTimers.firstItem;
|
|
||||||
|
|
||||||
while (_timer) {
|
|
||||||
KTimer *timer = _timer->thisItem;
|
|
||||||
LinkedItem<KTimer> *next = _timer->nextItem;
|
|
||||||
|
|
||||||
if (timer->triggerTimeMs <= timeMs) {
|
|
||||||
activeTimers.Remove(_timer);
|
|
||||||
KEventSet(&timer->event, true /* scheduler already locked */);
|
|
||||||
|
|
||||||
if (timer->callback) {
|
|
||||||
KRegisterAsyncTask(&timer->asyncTask, timer->callback);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
break; // Timers are kept sorted, so there's no point continuing.
|
|
||||||
}
|
|
||||||
|
|
||||||
_timer = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
KSpinlockRelease(&activeTimersSpinlock);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the next thread to execute.
|
// Get the next thread to execute.
|
||||||
Thread *newThread = local->currentThread = PickThread(local);
|
Thread *newThread = local->currentThread = PickThread(local);
|
||||||
|
|
||||||
|
|
|
@ -306,17 +306,12 @@ void KSemaphoreSet(KSemaphore *semaphore, uintptr_t u) {
|
||||||
KMutexRelease(&semaphore->mutex);
|
KMutexRelease(&semaphore->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool KEventSet(KEvent *event, bool schedulerAlreadyLocked, bool maybeAlreadySet) {
|
bool KEventSet(KEvent *event, bool maybeAlreadySet) {
|
||||||
if (event->state && !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");
|
KernelLog(LOG_ERROR, "Synchronisation", "event already set", "KEventSet - Attempt to set a event that had already been set\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!schedulerAlreadyLocked) {
|
KSpinlockAcquire(&scheduler.dispatchSpinlock);
|
||||||
KSpinlockAcquire(&scheduler.dispatchSpinlock);
|
|
||||||
} else {
|
|
||||||
KSpinlockAssertLocked(&scheduler.dispatchSpinlock);
|
|
||||||
}
|
|
||||||
|
|
||||||
volatile bool unblockedThreads = false;
|
volatile bool unblockedThreads = false;
|
||||||
|
|
||||||
if (!event->state) {
|
if (!event->state) {
|
||||||
|
@ -327,14 +322,12 @@ bool KEventSet(KEvent *event, bool schedulerAlreadyLocked, bool maybeAlreadySet)
|
||||||
unblockedThreads = true;
|
unblockedThreads = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
scheduler.NotifyObject(&event->blockedThreads, !event->autoReset /* if this is a manually reset event, unblock all the waiting threads */);
|
// If this is a manually reset event, unblock all the waiting threads.
|
||||||
|
scheduler.NotifyObject(&event->blockedThreads, !event->autoReset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!schedulerAlreadyLocked) {
|
KSpinlockRelease(&scheduler.dispatchSpinlock);
|
||||||
KSpinlockRelease(&scheduler.dispatchSpinlock);
|
|
||||||
}
|
|
||||||
|
|
||||||
return unblockedThreads;
|
return unblockedThreads;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -767,7 +767,7 @@ SYSCALL_IMPLEMENT(ES_SYSCALL_FILE_RESIZE) {
|
||||||
|
|
||||||
SYSCALL_IMPLEMENT(ES_SYSCALL_EVENT_SET) {
|
SYSCALL_IMPLEMENT(ES_SYSCALL_EVENT_SET) {
|
||||||
SYSCALL_HANDLE(argument0, KERNEL_OBJECT_EVENT, event, KEvent);
|
SYSCALL_HANDLE(argument0, KERNEL_OBJECT_EVENT, event, KEvent);
|
||||||
KEventSet(event, false, true);
|
KEventSet(event, true);
|
||||||
SYSCALL_RETURN(ES_SUCCESS, false);
|
SYSCALL_RETURN(ES_SUCCESS, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1220,7 +1220,7 @@ SYSCALL_IMPLEMENT(ES_SYSCALL_PROCESS_GET_STATE) {
|
||||||
SYSCALL_IMPLEMENT(ES_SYSCALL_SHUTDOWN) {
|
SYSCALL_IMPLEMENT(ES_SYSCALL_SHUTDOWN) {
|
||||||
SYSCALL_PERMISSION(ES_PERMISSION_SHUTDOWN);
|
SYSCALL_PERMISSION(ES_PERMISSION_SHUTDOWN);
|
||||||
shutdownAction = argument0;
|
shutdownAction = argument0;
|
||||||
KEventSet(&shutdownEvent, false, true);
|
KEventSet(&shutdownEvent, true);
|
||||||
SYSCALL_RETURN(ES_SUCCESS, false);
|
SYSCALL_RETURN(ES_SUCCESS, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue