Skip to content

Commit

Permalink
Add syscall option to yield to a specific task, make PS/2 driver auto…
Browse files Browse the repository at this point in the history
…matically yield to partner tasks when new data is available
  • Loading branch information
maxdev1 committed Feb 9, 2025
1 parent fa70241 commit 30347b9
Show file tree
Hide file tree
Showing 16 changed files with 147 additions and 64 deletions.
30 changes: 20 additions & 10 deletions applications/libps2driver/inc/libps2driver/ps2driver.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,9 @@ typedef int g_ps2_command;
/**
*
*/
struct g_ps2_request_header {
g_ps2_command command;
struct g_ps2_request_header
{
g_ps2_command command;
}__attribute__((packed));

/**
Expand All @@ -49,31 +50,40 @@ typedef int g_ps2_initialize_status;
/**
*
*/
struct g_ps2_initialize_request {
g_ps2_request_header header;
struct g_ps2_initialize_request
{
g_ps2_request_header header;
g_tid keyboardPartnerTask;
g_tid mousePartnerTask;
}__attribute__((packed));

/**
*
*/
struct g_ps2_initialize_response {
struct g_ps2_initialize_response
{
g_ps2_initialize_status status;
g_fd keyboardRead;
g_fd mouseRead;
g_fd keyboardRead;
g_fd mouseRead;
}__attribute__((packed));

/**
*
*/
struct g_ps2_mouse_packet {
int16_t x;
struct g_ps2_mouse_packet
{
int16_t x;
int16_t y;
uint8_t flags;
}__attribute__((packed));

/**
* Sends a request to the PS2 driver to allow this process to read data.
* If partner tasks are provided, the driver will yield control to them
* whenever new data is available.
*/
bool ps2DriverInitialize(g_fd* keyboardReadOut, g_fd* mouseReadOut);
bool ps2DriverInitialize(g_fd* keyboardReadOut, g_fd* mouseReadOut,
g_tid keyboardPartnerTask = G_TID_NONE,
g_tid mousePartnerTask = G_TID_NONE);

#endif
50 changes: 26 additions & 24 deletions applications/libps2driver/src/libps2driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,34 +21,36 @@
#include "libps2driver/ps2driver.hpp"
#include <ghost.h>

bool ps2DriverInitialize(g_fd* keyboardReadOut, g_fd* mouseReadOut)
bool ps2DriverInitialize(g_fd* keyboardReadOut, g_fd* mouseReadOut, g_tid keyboardPartnerTask, g_tid mousePartnerTask)
{

g_tid driver_tid = g_task_get_id(G_PS2_DRIVER_IDENTIFIER);
if(driver_tid == -1)
{
return false;
}
g_message_transaction transaction = g_get_message_tx_id();
g_tid driver_tid = g_task_get_id(G_PS2_DRIVER_IDENTIFIER);
if(driver_tid == -1)
{
return false;
}
g_message_transaction transaction = g_get_message_tx_id();

g_ps2_initialize_request request;
request.header.command = G_PS2_COMMAND_INITIALIZE;
g_send_message_t(driver_tid, &request, sizeof(g_ps2_initialize_request), transaction);
g_ps2_initialize_request request;
request.header.command = G_PS2_COMMAND_INITIALIZE;
request.keyboardPartnerTask = keyboardPartnerTask;
request.mousePartnerTask = mousePartnerTask;
g_send_message_t(driver_tid, &request, sizeof(g_ps2_initialize_request), transaction);

size_t buflen = sizeof(g_message_header) + sizeof(g_ps2_initialize_response);
uint8_t buf[buflen];
auto status = g_receive_message_t(buf, buflen, transaction);
g_ps2_initialize_response* response = (g_ps2_initialize_response*) G_MESSAGE_CONTENT(buf);
size_t buflen = sizeof(g_message_header) + sizeof(g_ps2_initialize_response);
uint8_t buf[buflen];
auto status = g_receive_message_t(buf, buflen, transaction);
g_ps2_initialize_response* response = (g_ps2_initialize_response*) G_MESSAGE_CONTENT(buf);

if(status == G_MESSAGE_RECEIVE_STATUS_SUCCESSFUL)
{
if(response->status == G_PS2_INITIALIZE_SUCCESS)
{
*keyboardReadOut = response->keyboardRead;
*mouseReadOut = response->mouseRead;
return true;
}
}
if(status == G_MESSAGE_RECEIVE_STATUS_SUCCESSFUL)
{
if(response->status == G_PS2_INITIALIZE_SUCCESS)
{
*keyboardReadOut = response->keyboardRead;
*mouseReadOut = response->mouseRead;
return true;
}
}

return false;
return false;
}
16 changes: 14 additions & 2 deletions applications/ps2driver/src/ps2driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,11 @@ g_fd keyboardWrite;
g_fd mouseRead;
g_fd mouseWrite;

g_tid keyboardPartnerTask = G_TID_NONE;
g_tid mousePartnerTask = G_TID_NONE;

int main()
{
uint32_t tid = g_get_tid();
if(!g_task_register_id(G_PS2_DRIVER_IDENTIFIER))
{
klog("ps2driver: could not register with task identifier '%s'", (char*) G_PS2_DRIVER_IDENTIFIER);
Expand Down Expand Up @@ -69,11 +71,17 @@ void ps2MouseCallback(int16_t x, int16_t y, uint8_t flags)
packet.y = y;
packet.flags = flags;
g_write(mouseWrite, &packet, sizeof(g_ps2_mouse_packet));

if(mousePartnerTask != G_TID_NONE)
g_yield_t(mousePartnerTask);
}

void ps2KeyboardCallback(uint8_t c)
{
g_write(keyboardWrite, &c, 1);

if(keyboardPartnerTask != G_TID_NONE)
g_yield_t(keyboardPartnerTask);
}

void ps2DriverReceiveMessages()
Expand Down Expand Up @@ -104,11 +112,15 @@ void ps2DriverReceiveMessages()
}
}

void ps2HandleCommandInitialize(g_ps2_initialize_request* request, g_tid requestingTaskId, g_message_transaction requestTransaction)
void ps2HandleCommandInitialize(g_ps2_initialize_request* request, g_tid requestingTaskId,
g_message_transaction requestTransaction)
{
g_pid targetPid = g_get_pid_for_tid(requestingTaskId);
g_pid sourcePid = g_get_pid();

keyboardPartnerTask = request->keyboardPartnerTask;
mousePartnerTask = request->mousePartnerTask;

g_ps2_initialize_response response;
response.status = G_PS2_STATUS_SUCCESS;
response.keyboardRead = g_clone_fd(keyboardRead, sourcePid, targetPid);
Expand Down
7 changes: 0 additions & 7 deletions applications/windowserver/src/events/event_processor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,6 @@ void event_processor_t::bufferKeyEvent(g_key_info keyInfo)
g_mutex_release(key_info_buffer_lock);
}

void event_processor_t::bufferCommandMessage(void* commandMessage)
{
g_mutex_acquire(command_message_buffer_lock);
command_message_buffer.push_back(commandMessage);
g_mutex_release(command_message_buffer_lock);
}

void event_processor_t::process()
{
processMouseState();
Expand Down
4 changes: 0 additions & 4 deletions applications/windowserver/src/events/event_processor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,6 @@ class event_processor_t
g_user_mutex key_info_buffer_lock = g_mutex_initialize();
void bufferKeyEvent(g_key_info keyInfo);

std::deque<void*> command_message_buffer;
g_user_mutex command_message_buffer_lock = g_mutex_initialize();
void bufferCommandMessage(void* commandMessage);

void process();

void translateKeyEvent(g_key_info& info);
Expand Down
6 changes: 3 additions & 3 deletions applications/windowserver/src/input/input_receiver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ static g_fd mouseIn;

void input_receiver_t::initialize()
{
ps2DriverInitialize(&keyboardIn, &mouseIn);
g_create_task((void*) startReceiveMouseEvents);
g_create_task((void*) startReceiveKeyEvents);
g_tid keyEventThread = g_create_task((void*) startReceiveKeyEvents);
g_tid mouseEventThread = g_create_task((void*) startReceiveMouseEvents);
ps2DriverInitialize(&keyboardIn, &mouseIn, keyEventThread, mouseEventThread);
}

void input_receiver_t::startReceiveKeyEvents()
Expand Down
19 changes: 14 additions & 5 deletions applications/windowserver/src/windowserver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ static windowserver_t* server;
static g_user_mutex dispatchLock = g_mutex_initialize_r(true);
static int framesTotal = 0;
static bool debugOn = false;
int debugBorderCycle = 0;

int main()
{
Expand Down Expand Up @@ -75,6 +76,7 @@ void windowserver_t::startInputHandlers()

void startOtherTasks()
{
g_task_register_id("windowserver/launcher");
// TODO not the windowservers job
g_spawn("/applications/desktop.bin", "", "", G_SECURITY_LEVEL_APPLICATION);
}
Expand All @@ -95,7 +97,9 @@ void windowserver_t::launch()

g_create_task((void*) &interfaceRegistrationThread);
g_create_task((void*) &startOtherTasks);
g_create_task_d((void*) startUpdateLoop, this);

updateTask = g_create_task_d((void*) startUpdateLoop, this);
renderTask = g_get_tid();
renderLoop(screenBounds);
}

Expand All @@ -108,7 +112,7 @@ void windowserver_t::createVitalComponents(g_rectangle screenBounds)
stateLabel->setTitle("");
stateLabel->setAlignment(g_text_alignment::RIGHT);
stateLabel->setVisible(false);
stateLabel->setBounds(g_rectangle(10, screenBounds.height - 30, screenBounds.width - 20, 30));
stateLabel->setBounds(g_rectangle(10, screenBounds.height - 100, screenBounds.width - 20, 30));
instance()->stateLabel->setColor(RGB(255, 255, 255));
screen->addChild(stateLabel);

Expand Down Expand Up @@ -146,7 +150,6 @@ void windowserver_t::startUpdateLoop(windowserver_t* self)
self->updateLoop();
}


void windowserver_t::updateLoop()
{
g_task_register_id("windowserver/updater");
Expand All @@ -168,6 +171,7 @@ void windowserver_t::updateLoop()
void windowserver_t::requestUpdate() const
{
g_mutex_release(updateLock);
g_yield_t(updateTask);
}


Expand Down Expand Up @@ -196,6 +200,7 @@ void windowserver_t::renderLoop(g_rectangle screenBounds)
void windowserver_t::requestRender() const
{
g_mutex_release(renderLock);
g_yield_t(renderTask);
}

void windowserver_t::output(graphics_t* graphics) const
Expand All @@ -210,10 +215,14 @@ void windowserver_t::output(graphics_t* graphics) const
auto cr = graphics->acquireContext();
if(cr)
{
debugBorderCycle++;
if(debugBorderCycle > 100)
debugBorderCycle = 0;

cairo_save(cr);
cairo_set_line_width(cr, 2);
cairo_rectangle(cr, invalid.x, invalid.y, invalid.width, invalid.height);
cairo_set_source_rgba(cr, 0, 1, 0, 1);
cairo_set_source_rgba(cr, 0, ((double) (debugBorderCycle + 100)) / 255, 0, 1);
cairo_stroke(cr);
cairo_restore(cr);
graphics->releaseContext();
Expand Down Expand Up @@ -320,7 +329,7 @@ void windowserver_t::fpsCounter()
void windowserver_t::setDebug(bool cond)
{
debugOn = cond;
server->stateLabel->setVisible(cond);
// server->stateLabel->setVisible(cond);
}

bool windowserver_t::isDebug()
Expand Down
2 changes: 2 additions & 0 deletions applications/windowserver/src/windowserver.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ class item_container_t;
*/
class windowserver_t
{
g_tid updateTask = G_TID_NONE;
g_tid renderTask = G_TID_NONE;
g_user_mutex updateLock = g_mutex_initialize();
g_user_mutex renderLock = g_mutex_initialize();

Expand Down
5 changes: 4 additions & 1 deletion kernel/src/kernel/calls/syscall_tasking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "kernel/memory/memory.hpp"
#include "kernel/tasking/user_mutex.hpp"
#include "kernel/system/interrupts/interrupts.hpp"
#include "kernel/tasking/scheduler/scheduler.hpp"
#include "kernel/tasking/tasking_directory.hpp"
#include "kernel/tasking/clock.hpp"
#include "kernel/utils/wait_queue.hpp"
Expand All @@ -38,8 +39,10 @@ void syscallSleep(g_task* task, g_syscall_sleep* data)
taskingYield();
}

void syscallYield(g_task* task)
void syscallYield(g_task* task, g_syscall_yield* data)
{
if(data->target != G_TID_NONE)
schedulerPrefer(data->target);
taskingYield();
}

Expand Down
2 changes: 1 addition & 1 deletion kernel/src/kernel/calls/syscall_tasking.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ void syscallExit(g_task* task, g_syscall_exit* data);

void syscallExitTask(g_task* task);

void syscallYield(g_task* task);
void syscallYield(g_task* task, g_syscall_yield* data);

void syscallGetProcessId(g_task* task, g_syscall_get_pid* data);

Expand Down
3 changes: 0 additions & 3 deletions kernel/src/kernel/system/interrupts/interrupts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@

#include "kernel/system/interrupts/interrupts.hpp"
#include "kernel/calls/syscall.hpp"
#include "kernel/memory/gdt.hpp"
#include "kernel/system/interrupts/apic/ioapic.hpp"
#include "kernel/system/interrupts/apic/lapic.hpp"
#include "kernel/system/interrupts/exceptions.hpp"
Expand All @@ -30,8 +29,6 @@
#include "kernel/system/timing/pit.hpp"
#include "kernel/tasking/clock.hpp"
#include "kernel/tasking/tasking.hpp"
#include "kernel/tasking/tasking_state.hpp"
#include "kernel/utils/wait_queue.hpp"
#include "shared/panic.hpp"

void _interruptsSendEndOfInterrupt(uint8_t irq);
Expand Down
5 changes: 5 additions & 0 deletions kernel/src/kernel/tasking/scheduler/scheduler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,9 @@ void schedulerSchedule(g_tasking_local* local);
*/
void schedulerDump();

/**
* Sets a task as the "preferred task" for scheduling.
*/
void schedulerPrefer(g_tid task);

#endif
Loading

0 comments on commit 30347b9

Please sign in to comment.