1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 18:17:45 +00:00

Kernel: Move block condition evaluation out of the Scheduler

This makes the Scheduler a lot leaner by not having to evaluate
block conditions every time it is invoked. Instead evaluate them as
the states change, and unblock threads at that point.

This also implements some more waitid/waitpid/wait features and
behavior. For example, WUNTRACED and WNOWAIT are now supported. And
wait will now not return EINTR when SIGCHLD is delivered at the
same time.
This commit is contained in:
Tom 2020-11-29 16:05:27 -07:00 committed by Andreas Kling
parent 6a620562cc
commit 046d6855f5
53 changed files with 2027 additions and 930 deletions

View file

@ -45,6 +45,11 @@ MasterPTY::MasterPTY(unsigned index)
auto process = Process::current();
set_uid(process->uid());
set_gid(process->gid());
m_buffer.set_unblock_callback([this]() {
if (m_slave)
evaluate_block_conditions();
});
}
MasterPTY::~MasterPTY()

View file

@ -71,10 +71,11 @@ void SlavePTY::on_master_write(const UserOrKernelBuffer& buffer, ssize_t size)
{
ssize_t nread = buffer.read_buffered<128>(size, [&](const u8* data, size_t data_size) {
for (size_t i = 0; i < data_size; ++i)
emit(data[i]);
emit(data[i], false);
return (ssize_t)data_size;
});
(void)nread;
if (nread > 0)
evaluate_block_conditions();
}
ssize_t SlavePTY::on_tty_write(const UserOrKernelBuffer& data, ssize_t size)
@ -108,4 +109,9 @@ KResult SlavePTY::close()
return KSuccess;
}
FileBlockCondition& SlavePTY::block_condition()
{
return m_master->block_condition();
}
}

View file

@ -42,6 +42,8 @@ public:
time_t time_of_last_write() const { return m_time_of_last_write; }
virtual FileBlockCondition& block_condition() override;
private:
// ^TTY
virtual String tty_name() const override;

View file

@ -24,6 +24,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <AK/ScopeGuard.h>
#include <Kernel/Process.h>
#include <Kernel/TTY/TTY.h>
#include <LibC/errno_numbers.h>
@ -64,6 +65,7 @@ KResultOr<size_t> TTY::read(FileDescription&, size_t, UserOrKernelBuffer& buffer
size = m_input_buffer.size();
ssize_t nwritten;
bool need_evaluate_block_conditions = false;
if (in_canonical_mode()) {
nwritten = buffer.write_buffered<512>(size, [&](u8* data, size_t data_size) {
size_t i = 0;
@ -73,6 +75,7 @@ KResultOr<size_t> TTY::read(FileDescription&, size_t, UserOrKernelBuffer& buffer
//Here we handle a ^D line, so we don't add the
//character to the output.
m_available_lines--;
need_evaluate_block_conditions = true;
break;
} else if (ch == '\n' || is_eol(ch)) {
data[i] = ch;
@ -93,6 +96,8 @@ KResultOr<size_t> TTY::read(FileDescription&, size_t, UserOrKernelBuffer& buffer
}
if (nwritten < 0)
return KResult(nwritten);
if (nwritten > 0 || need_evaluate_block_conditions)
evaluate_block_conditions();
return (size_t)nwritten;
}
@ -145,7 +150,7 @@ bool TTY::is_werase(u8 ch) const
return ch == m_termios.c_cc[VWERASE];
}
void TTY::emit(u8 ch)
void TTY::emit(u8 ch, bool do_evaluate_block_conditions)
{
if (should_generate_signals()) {
if (ch == m_termios.c_cc[VINFO]) {
@ -173,6 +178,11 @@ void TTY::emit(u8 ch)
}
}
ScopeGuard guard([&]() {
if (do_evaluate_block_conditions)
evaluate_block_conditions();
});
if (in_canonical_mode()) {
if (is_eof(ch)) {
m_available_lines++;
@ -218,6 +228,8 @@ void TTY::do_backspace()
echo(8);
echo(' ');
echo(8);
evaluate_block_conditions();
}
}
@ -231,6 +243,7 @@ void TTY::erase_word()
//Note: if we have leading whitespace before the word
//we want to delete we have to also delete that.
bool first_char = false;
bool did_dequeue = false;
while (can_do_backspace()) {
u8 ch = m_input_buffer.last();
if (ch == ' ' && first_char)
@ -238,16 +251,23 @@ void TTY::erase_word()
if (ch != ' ')
first_char = true;
m_input_buffer.dequeue_end();
did_dequeue = true;
erase_character();
}
if (did_dequeue)
evaluate_block_conditions();
}
void TTY::kill_line()
{
bool did_dequeue = false;
while (can_do_backspace()) {
m_input_buffer.dequeue_end();
did_dequeue = true;
erase_character();
}
if (did_dequeue)
evaluate_block_conditions();
}
void TTY::erase_character()
@ -277,6 +297,7 @@ void TTY::flush_input()
{
m_available_lines = 0;
m_input_buffer.clear();
evaluate_block_conditions();
}
void TTY::set_termios(const termios& t)
@ -330,7 +351,7 @@ int TTY::ioctl(FileDescription&, unsigned request, FlatPtr arg)
return -EPERM;
if (process && pgid != process->pgid())
return -EPERM;
m_pg = *process_group;
m_pg = process_group;
if (process) {
if (auto parent = Process::from_pid(process->ppid())) {

View file

@ -72,7 +72,7 @@ protected:
void set_size(unsigned short columns, unsigned short rows);
TTY(unsigned major, unsigned minor);
void emit(u8);
void emit(u8, bool do_evaluate_block_conditions = false);
virtual void echo(u8) = 0;
bool can_do_backspace() const;