From 86771ec0f0631eaefb7be8e9dba75a18135df8cc Mon Sep 17 00:00:00 2001 From: Baptiste Wicht Date: Wed, 29 Jan 2014 22:16:10 +0100 Subject: [PATCH] Prepare basic implementation of a sleep queue inside the keyboard driver --- kernel/include/keyboard.hpp | 2 +- kernel/include/sleep_queue.hpp | 60 ++++++++++++++++++++++++++++++++++ kernel/src/keyboard.cpp | 37 ++++++++++++++++----- kernel/src/system_calls.cpp | 7 +--- 4 files changed, 91 insertions(+), 15 deletions(-) create mode 100644 kernel/include/sleep_queue.hpp diff --git a/kernel/include/keyboard.hpp b/kernel/include/keyboard.hpp index 4902a872..14db4d98 100644 --- a/kernel/include/keyboard.hpp +++ b/kernel/include/keyboard.hpp @@ -24,7 +24,7 @@ char get_char(); char key_to_ascii(uint8_t key); char shift_key_to_ascii(uint8_t key); -char get_char_blocking(); +void get_char_blocking(); } diff --git a/kernel/include/sleep_queue.hpp b/kernel/include/sleep_queue.hpp new file mode 100644 index 00000000..fcedfc8c --- /dev/null +++ b/kernel/include/sleep_queue.hpp @@ -0,0 +1,60 @@ +//======================================================================= +// Copyright Baptiste Wicht 2013-2014. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= + +#ifndef SLEEP_QUEUE_H +#define SLEEP_QUEUE_H + +#include "stl/queue.hpp" +#include "stl/lock_guard.hpp" + +#include "spinlock.hpp" +#include "scheduler.hpp" + +struct sleep_queue { +private: + mutable spinlock lock; + + std::queue queue; + +public: + bool empty() const { + std::lock_guard l(lock); + + return queue.empty(); + } + + scheduler::pid_t wake_up(){ + std::lock_guard l(lock); + + //Get the first process + auto pid = queue.top(); + + //Indicate to the scheduler that this process will be able + //to run + scheduler::unblock_process(pid); + + //Remove the process from the queue + queue.pop(); + + return pid; + } + + void sleep(){ + std::lock_guard l(lock); + + //Get the current process information + auto pid = scheduler::get_pid(); + + //This process will sleep + scheduler::block_process(pid); + + //Enqueue the process in the sleep queue + queue.push(pid); + } +}; + +#endif diff --git a/kernel/src/keyboard.cpp b/kernel/src/keyboard.cpp index d57ac77c..d9521ca5 100644 --- a/kernel/src/keyboard.cpp +++ b/kernel/src/keyboard.cpp @@ -10,6 +10,7 @@ #include "kernel_utils.hpp" #include "semaphore.hpp" #include "spinlock.hpp" +#include "sleep_queue.hpp" namespace { @@ -93,22 +94,31 @@ char shifted_qwertz[128] = { const uint8_t BUFFER_SIZE = 64; +//TODO Encapsulate the buffer char input_buffer[BUFFER_SIZE]; volatile uint8_t start; volatile uint8_t count; spinlock lock; -semaphore sem; +sleep_queue queue; void keyboard_handler(const interrupt::syscall_regs&){ auto key = static_cast(in_byte(0x60)); + std::lock_guard l(lock); + if(count == BUFFER_SIZE){ //The buffer is full, we loose the characters } else { - auto end = (start + count) % BUFFER_SIZE; - input_buffer[end] = key; - ++count; + if(queue.empty()){ + auto end = (start + count) % BUFFER_SIZE; + input_buffer[end] = key; + ++count; + } else { + auto pid = queue.wake_up(); + + //TODO Give key to process pid + } } } @@ -119,12 +129,23 @@ void keyboard::install_driver(){ start = 0; count = 0; - - sem.init(0); } -char keyboard::get_char_blocking(){ - //TODO +void keyboard::get_char_blocking(){ + std::lock_guard l(lock); + + if(count > 0){ + auto key = input_buffer[start]; + start = (start + 1) % BUFFER_SIZE; + --count; + + auto pid = scheduler::current_pid(); + + //TODO Give key to process pid + } else { + //Wait for a char + queue.sleep(); + } } //TODO Once shell is user mode, can be removed diff --git a/kernel/src/system_calls.cpp b/kernel/src/system_calls.cpp index dff00313..bbeaf929 100644 --- a/kernel/src/system_calls.cpp +++ b/kernel/src/system_calls.cpp @@ -24,11 +24,6 @@ void sc_print_digit(const interrupt::syscall_regs& regs){ k_print(regs.rbx); } -void sc_get_char(const interrupt::syscall_regs& regs){ - auto c = keyboard::get_char_blocking(); - //TODO -} - } //End of anonymous namespace void system_call_entry(const interrupt::syscall_regs& regs){ @@ -48,7 +43,7 @@ void system_call_entry(const interrupt::syscall_regs& regs){ break; case 3: - sc_get_char(regs); + keyboard::get_char_blocking(); break; case 0x666: