Skip to content

Commit 1a537b5

Browse files
committed
Simplify userspace IRQ handling with g_await_irq; remove "non-interruptible" pipes (dumb idea); add call to create task with core affinity
1 parent 48f2818 commit 1a537b5

30 files changed

+264
-224
lines changed

applications/libps2/src/ps2.cpp

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -54,41 +54,27 @@ ps2_status_t ps2Initialize(void (*mouseCallback)(int16_t, int16_t, uint8_t, int8
5454
g_irq_create_redirect(1, 1);
5555
g_irq_create_redirect(12, 12);
5656

57-
g_open_irq_device(1, &keyIrqIn);
58-
g_create_task((void*) &ps2ReadKeyIrq);
59-
g_open_irq_device(12, &mouseIrqIn);
60-
g_create_task((void*) &ps2ReadMouseIrq);
57+
g_create_task_a((void*) &ps2ReadKeyIrq, 0);
58+
g_create_task_a((void*) &ps2ReadMouseIrq, 0);
6159
return G_PS2_STATUS_SUCCESS;
6260
}
6361

6462
void ps2ReadKeyIrq()
6563
{
6664
g_task_register_id("libps2/read-key");
67-
uint8_t buf[1];
6865
for(;;)
6966
{
70-
g_fs_read_status stat;
71-
g_read_s(keyIrqIn, buf, 1, &stat);
72-
if(stat == G_FS_READ_BUSY)
73-
{
74-
g_sleep(10);
75-
}
67+
g_await_irq_t(1, 1000);
7668
ps2CheckForData();
7769
}
7870
}
7971

8072
void ps2ReadMouseIrq()
8173
{
8274
g_task_register_id("libps2/read-mouse");
83-
uint8_t buf[1];
8475
for(;;)
8576
{
86-
g_fs_read_status stat;
87-
g_read_s(mouseIrqIn, buf, 1, &stat);
88-
if(stat == G_FS_READ_BUSY)
89-
{
90-
g_sleep(10);
91-
}
77+
g_await_irq_t(12, 1000);
9278
ps2CheckForData();
9379
}
9480
}
@@ -182,6 +168,15 @@ ps2_status_t ps2InitializeMouse()
182168

183169
void ps2HandleMouseData(uint8_t value)
184170
{
171+
static uint64_t lastPacketTime = 0;
172+
uint64_t now = g_millis();
173+
174+
// Reset packet state if too much time has passed
175+
if(mousePacketNumber > 0 && (now - lastPacketTime > 50))
176+
mousePacketNumber = 0;
177+
178+
lastPacketTime = now;
179+
185180
if(mousePacketNumber == 0)
186181
{
187182
mousePacketBuffer[0] = value;

applications/windowserver/src/windowserver.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,8 +176,7 @@ void windowserver_t::updateLoop(const g_rectangle& screenBounds) const
176176
output(&global);
177177

178178
framesTotal++;
179-
if(!g_mutex_acquire_to(updateLock, 1000))
180-
klog("Times updated: %i", framesTotal);
179+
g_mutex_acquire_to(updateLock, 1000);
181180

182181
auto now = g_millis();
183182
if(now - lastUpdate < 10)

kernel/src/kernel/calls/syscall.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,6 @@ void syscallRegisterAll()
146146
_syscallRegister(G_SYSCALL_FS_OPEN_DIRECTORY, (g_syscall_handler) syscallFsOpenDirectory, true);
147147
_syscallRegister(G_SYSCALL_FS_READ_DIRECTORY, (g_syscall_handler) syscallFsReadDirectory, true);
148148
_syscallRegister(G_SYSCALL_FS_CLOSE_DIRECTORY, (g_syscall_handler) syscallFsCloseDirectory, true);
149-
_syscallRegister(G_SYSCALL_OPEN_IRQ_DEVICE, (g_syscall_handler) syscallOpenIrqDevice, true);
150149
_syscallRegister(G_SYSCALL_FS_REAL_PATH, (g_syscall_handler) syscallFsRealPath, true);
151150

152151
// System
@@ -155,6 +154,7 @@ void syscallRegisterAll()
155154
_syscallRegister(G_SYSCALL_TEST, (g_syscall_handler) syscallTest);
156155
_syscallRegister(G_SYSCALL_CALL_VM86, (g_syscall_handler) syscallCallVm86);
157156
_syscallRegister(G_SYSCALL_IRQ_CREATE_REDIRECT, (g_syscall_handler) syscallIrqCreateRedirect);
157+
_syscallRegister(G_SYSCALL_AWAIT_IRQ, (g_syscall_handler) syscallAwaitIrq, true);
158158

159159
// Kernquery
160160
_syscallRegister(G_SYSCALL_KERNQUERY, (g_syscall_handler) syscallKernQuery);

kernel/src/kernel/calls/syscall_filesystem.cpp

Lines changed: 1 addition & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ void syscallFsTell(g_task* task, g_syscall_fs_tell* data)
9898
void syscallFsPipe(g_task* task, g_syscall_fs_pipe* data)
9999
{
100100
g_fs_node* pipeNode;
101-
data->status = filesystemCreatePipe(data->blocking, &pipeNode, false);
101+
data->status = filesystemCreatePipe(data->blocking, &pipeNode);
102102

103103
if(data->status != G_FS_PIPE_SUCCESSFUL)
104104
{
@@ -136,41 +136,6 @@ void syscallFsPipe(g_task* task, g_syscall_fs_pipe* data)
136136
data->status = G_FS_PIPE_SUCCESSFUL;
137137
}
138138

139-
void syscallOpenIrqDevice(g_task* task, g_syscall_open_irq_device* data)
140-
{
141-
if(task->securityLevel <= G_SECURITY_LEVEL_DRIVER)
142-
{
143-
g_irq_device* irqDevice = requestsGetIrqDevice(data->irq);
144-
if(!irqDevice)
145-
{
146-
data->status = G_OPEN_IRQ_DEVICE_STATUS_ERROR;
147-
logInfo("%! task %i: failed to retrieve device for irq %i", "irq", task->id, data->irq);
148-
return;
149-
}
150-
151-
irqDevice->task = task->id;
152-
153-
g_fd fd;
154-
g_file_flag_mode readFlags = (G_FILE_FLAG_MODE_READ | G_FILE_FLAG_MODE_BLOCKING);
155-
if(filesystemOpenNodeFd(irqDevice->node, readFlags, task->process->id, &fd) == G_FS_OPEN_SUCCESSFUL)
156-
{
157-
data->status = G_OPEN_IRQ_DEVICE_STATUS_SUCCESSFUL;
158-
data->fd = fd;
159-
logDebug("%! task %i: opened device for IRQ %i", "irq", task->id, data->irq);
160-
}
161-
else
162-
{
163-
data->status = G_OPEN_IRQ_DEVICE_STATUS_ERROR;
164-
logInfo("%! task %i: failed to open device for IRQ %i", "irq", task->id, data->irq);
165-
}
166-
}
167-
else
168-
{
169-
data->status = G_OPEN_IRQ_DEVICE_STATUS_NOT_PERMITTED;
170-
logInfo("%! task %i: not permitted to open device for irq %i", "irq", task->id, data->irq);
171-
}
172-
}
173-
174139
void syscallFsOpenDirectory(g_task* task, g_syscall_fs_open_directory* data)
175140
{
176141
auto findRes = filesystemFind(nullptr, data->path);

kernel/src/kernel/calls/syscall_filesystem.hpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,6 @@ void syscallFsCloneFd(g_task* task, g_syscall_fs_clonefd* data);
4646

4747
void syscallFsPipe(g_task* task, g_syscall_fs_pipe* data);
4848

49-
void syscallOpenIrqDevice(g_task* task, g_syscall_open_irq_device* data);
50-
5149
void syscallFsOpenDirectory(g_task* task, g_syscall_fs_open_directory* data);
5250

5351
void syscallFsReadDirectory(g_task* task, g_syscall_fs_read_directory* data);

kernel/src/kernel/calls/syscall_system.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2020

2121
#include "kernel/calls/syscall_system.hpp"
22+
#include "kernel/system/interrupts/interrupts.hpp"
23+
#include "kernel/system/interrupts/requests.hpp"
24+
#include "kernel/system/processor/processor.hpp"
25+
#include "kernel/tasking/clock.hpp"
2226
#include "kernel/filesystem/filesystem.hpp"
2327
#include "kernel/system/interrupts/apic/ioapic.hpp"
2428
#include "shared/logger/logger.hpp"
@@ -108,3 +112,32 @@ void syscallIrqCreateRedirect(g_task* task, g_syscall_irq_create_redirect* data)
108112

109113
ioapicCreateRedirectionEntry(data->source, data->irq, 0);
110114
}
115+
116+
void syscallAwaitIrq(g_task* task, g_syscall_await_irq* data)
117+
{
118+
if(task->securityLevel > G_SECURITY_LEVEL_DRIVER)
119+
return;
120+
121+
if(processorGetCurrentId() != 0)
122+
{
123+
logWarn("%! awaiting IRQs only possible on core 0", "call");
124+
return taskingExit();
125+
}
126+
127+
requestsSetHandlerTask(data->irq, task->id);
128+
129+
if(data->timeout)
130+
clockUnwaitForTime(task->id);
131+
132+
INTERRUPTS_PAUSE;
133+
mutexAcquire(&task->lock);
134+
task->status = G_TASK_STATUS_WAITING;
135+
task->waitsFor = "irq";
136+
mutexRelease(&task->lock);
137+
taskingYield();
138+
139+
if(data->timeout)
140+
clockWaitForTime(task->id, clockGetLocal()->time + data->timeout);
141+
142+
INTERRUPTS_RESUME;
143+
}

kernel/src/kernel/calls/syscall_system.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,6 @@ void syscallCallVm86(g_task* task, g_syscall_call_vm86* data);
3434

3535
void syscallIrqCreateRedirect(g_task* task, g_syscall_irq_create_redirect* data);
3636

37+
void syscallAwaitIrq(g_task* task, g_syscall_await_irq* data);
38+
3739
#endif

kernel/src/kernel/calls/syscall_tasking.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,14 @@ void syscallCreateTask(g_task* task, g_syscall_create_task* data)
171171
newTask->userEntry.data = data->userData;
172172
data->threadId = newTask->id;
173173
data->status = G_CREATE_TASK_STATUS_SUCCESSFUL;
174-
taskingAssignBalanced(newTask);
174+
175+
if(data->coreAffinity == G_TASK_CORE_AFFINITY_NONE)
176+
{
177+
taskingAssignBalanced(newTask);
178+
} else
179+
{
180+
taskingAssignOnCore(data->coreAffinity, newTask);
181+
}
175182
}
176183
else
177184
{

kernel/src/kernel/filesystem/filesystem.cpp

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -379,17 +379,6 @@ g_fs_read_status filesystemRead(g_task* task, g_fd fd, uint8_t* buffer, uint64_t
379379
return G_FS_READ_INVALID_FD;
380380
}
381381

382-
if(node->nonInterruptible)
383-
{
384-
// TODO I don't have a better idea right now, but sometimes the PS/2
385-
// device does not seem to fire an interrupt even though data is available
386-
// or maybe not, because we are reading in a loop. But this causes the
387-
// ps2driver to freeze because it has nothing to read from the blocking
388-
// pipe, so to avoid this we wake after some time:
389-
clockWaitForTime(task->id, clockGetLocal()->time + 1000);
390-
interruptsDisable();
391-
}
392-
393382
int64_t read;
394383
g_fs_read_status status;
395384
while((status = filesystemRead(node, buffer, descriptor->offset, length, &read)) == G_FS_READ_BUSY
@@ -408,18 +397,11 @@ g_fs_read_status filesystemRead(g_task* task, g_fd fd, uint8_t* buffer, uint64_t
408397
delegate->waitForRead(task->id, node);
409398
taskingYield();
410399
INTERRUPTS_RESUME;
411-
412-
// TODO
413-
if(node->nonInterruptible && clockHasTimedOut(task->id))
414-
{
415-
status = G_FS_READ_BUSY;
416-
break;
417-
}
418400
}
401+
419402
if(read > 0)
420-
{
421403
descriptor->offset += read;
422-
}
404+
423405
*outRead = read;
424406
return status;
425407
}
@@ -471,9 +453,6 @@ g_fs_write_status filesystemWrite(g_task* task, g_fd fd, uint8_t* buffer, uint64
471453
if(!node)
472454
return G_FS_WRITE_INVALID_FD;
473455

474-
if(node->nonInterruptible)
475-
interruptsDisable();
476-
477456
uint64_t startOffset = descriptor->offset;
478457
if(descriptor->openFlags & G_FILE_FLAG_MODE_APPEND)
479458
{
@@ -538,7 +517,7 @@ g_fs_open_status filesystemTruncate(g_fs_node* file)
538517
return delegate->truncate(file);
539518
}
540519

541-
g_fs_pipe_status filesystemCreatePipe(g_bool blocking, g_fs_node** outPipeNode, bool nonInterruptible)
520+
g_fs_pipe_status filesystemCreatePipe(g_bool blocking, g_fs_node** outPipeNode)
542521
{
543522
g_fs_phys_id pipeId;
544523
g_fs_pipe_status status = pipeCreate(&pipeId);
@@ -558,7 +537,6 @@ g_fs_pipe_status filesystemCreatePipe(g_bool blocking, g_fs_node** outPipeNode,
558537
g_fs_node* pipeNode = filesystemCreateNode(G_FS_NODE_TYPE_PIPE, pipeName);
559538
pipeNode->physicalId = pipeId;
560539
pipeNode->blocking = true; // TODO Why does using the parameter freeze everything?
561-
pipeNode->nonInterruptible = nonInterruptible;
562540
filesystemAddChild(pipesFolder, pipeNode);
563541
*outPipeNode = pipeNode;
564542
return G_FS_PIPE_SUCCESSFUL;

kernel/src/kernel/filesystem/filesystem.hpp

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,7 @@ struct g_fs_node
4848

4949
bool blocking;
5050
bool upToDate;
51-
52-
/**
53-
* If a node is non-interruptible, it means that during any read or write
54-
* operations, interrupts will be disabled. This is important for example
55-
* for IRQ-device pipes to avoid self-deadlocking.
56-
*/
57-
bool nonInterruptible;
58-
};
51+
};
5952

6053
/**
6154
* An entry in the node tree.
@@ -217,7 +210,7 @@ g_fs_open_status filesystemTruncate(g_fs_node* file);
217210
/**
218211
* Creates a new pipe on the filesystem.
219212
*/
220-
g_fs_pipe_status filesystemCreatePipe(g_bool blocking, g_fs_node** outPipeNode, bool nonInterruptible);
213+
g_fs_pipe_status filesystemCreatePipe(g_bool blocking, g_fs_node** outPipeNode);
221214

222215
/**
223216
* Writes the absolute path of node into the given buffer (which must be of G_PATH_MAX bytes size).

kernel/src/kernel/system/interrupts/interrupts.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2020

2121
#include "kernel/system/interrupts/interrupts.hpp"
22+
#include "shared/logger/logger.hpp"
2223
#include "kernel/calls/syscall.hpp"
2324
#include "kernel/system/interrupts/apic/ioapic.hpp"
2425
#include "kernel/system/interrupts/apic/lapic.hpp"
@@ -95,9 +96,8 @@ extern "C" volatile g_processor_state* _interruptHandler(volatile g_processor_st
9596
}
9697
else
9798
{
98-
requestsWriteToIrqDevice(irq);
99+
requestsHandle(task, irq);
99100
}
100-
101101
_interruptsSendEndOfInterrupt(irq);
102102
}
103103

0 commit comments

Comments
 (0)