From 065f0aee35331cd721c163a66ca68183f5ff4517 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Thu, 1 Nov 2018 13:39:28 +0100 Subject: [PATCH] Preallocate the maximum number of FileHandle pointers (fds) in every process. This could even use a more specific data structure since it doesn't need the grow/shrink capabilities of a vector. --- AK/Vector.h | 11 +++++++++++ Kernel/ProcFileSystem.cpp | 2 +- Kernel/Process.cpp | 34 +++++++++++++++++++++------------- Kernel/Process.h | 8 ++++---- 4 files changed, 37 insertions(+), 18 deletions(-) diff --git a/AK/Vector.h b/AK/Vector.h index 8eb757100a5..db28da6f223 100644 --- a/AK/Vector.h +++ b/AK/Vector.h @@ -172,6 +172,17 @@ public: m_impl = newImpl; } + void resize(size_t new_size) + { + ASSERT(new_size >= size()); + if (!new_size) + return; + ensureCapacity(new_size); + for (size_t i = size(); i < new_size; ++i) + new (m_impl->slot(i)) T; + m_impl->m_size = new_size; + } + class Iterator { public: bool operator!=(const Iterator& other) { return m_index != other.m_index; } diff --git a/Kernel/ProcFileSystem.cpp b/Kernel/ProcFileSystem.cpp index df860911ae4..1c1c589ec0e 100644 --- a/Kernel/ProcFileSystem.cpp +++ b/Kernel/ProcFileSystem.cpp @@ -203,7 +203,7 @@ ByteBuffer procfs$summary() toString(process->state()), process->parentPID(), process->timesScheduled(), - process->fileHandleCount(), + process->number_of_open_file_descriptors(), process->tty() ? strrchr(process->tty()->ttyName().characters(), '/') + 1 : "n/a", process->name().characters()); } diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index d64c6026228..c6c6fb3a041 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -409,14 +409,12 @@ Process::Process(String&& name, uid_t uid, gid_t gid, pid_t parentPID, RingLevel m_pageDirectory = (dword*)kmalloc_page_aligned(4096); MM.populate_page_directory(*this); + m_file_descriptors.resize(m_max_open_file_descriptors); + if (tty) { - m_fileHandles.append(tty->open(O_RDONLY)); // stdin - m_fileHandles.append(tty->open(O_WRONLY)); // stdout - m_fileHandles.append(tty->open(O_WRONLY)); // stderr - } else { - m_fileHandles.append(nullptr); // stdin - m_fileHandles.append(nullptr); // stdout - m_fileHandles.append(nullptr); // stderr + m_file_descriptors[0] = tty->open(O_RDONLY); + m_file_descriptors[1] = tty->open(O_WRONLY); + m_file_descriptors[2] = tty->open(O_WRONLY); } m_nextRegion = LinearAddress(0x10000000); @@ -667,7 +665,7 @@ bool scheduleNewProcess() if (process->state() == Process::BlockedRead) { ASSERT(process->m_fdBlockedOnRead != -1); - if (process->m_fileHandles[process->m_fdBlockedOnRead]->hasDataAvailableForRead()) { + if (process->m_file_descriptors[process->m_fdBlockedOnRead]->hasDataAvailableForRead()) { process->unblock(); continue; } @@ -782,8 +780,8 @@ FileHandle* Process::fileHandleIfExists(int fd) { if (fd < 0) return nullptr; - if ((unsigned)fd < m_fileHandles.size()) - return m_fileHandles[fd].ptr(); + if ((unsigned)fd < m_file_descriptors.size()) + return m_file_descriptors[fd].ptr(); return nullptr; } @@ -943,13 +941,23 @@ int Process::sys$getcwd(char* buffer, size_t size) return -ENOTIMPL; } +size_t Process::number_of_open_file_descriptors() const +{ + size_t count = 0; + for (auto& handle : m_file_descriptors) { + if (handle) + ++count; + } + return count; +} + int Process::sys$open(const char* path, int options) { #ifdef DEBUG_IO kprintf("Process::sys$open(): PID=%u, path=%s {%u}\n", m_pid, path, pathLength); #endif VALIDATE_USER_READ(path, strlen(path)); - if (m_fileHandles.size() >= m_maxFileHandles) + if (number_of_open_file_descriptors() >= m_max_open_file_descriptors) return -EMFILE; int error; auto handle = VirtualFileSystem::the().open(path, error, options, cwdInode()); @@ -958,9 +966,9 @@ int Process::sys$open(const char* path, int options) if (options & O_DIRECTORY && !handle->isDirectory()) return -ENOTDIR; // FIXME: This should be handled by VFS::open. - int fd = m_fileHandles.size(); + int fd = m_file_descriptors.size(); handle->setFD(fd); - m_fileHandles.append(move(handle)); + m_file_descriptors.append(move(handle)); return fd; } diff --git a/Kernel/Process.h b/Kernel/Process.h index d4edfba82fc..78d5bfccb47 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -124,8 +124,6 @@ public: pid_t waitee() const { return m_waitee; } - size_t fileHandleCount() const { return m_fileHandles.size(); } - dword framePtr() const { return m_tss.ebp; } dword stackPtr() const { return m_tss.esp; } dword stackTop() const { return m_tss.ss == 0x10 ? m_stackTop0 : m_stackTop3; } @@ -137,6 +135,8 @@ public: InodeIdentifier cwdInode() const { return m_cwd ? m_cwd->inode : InodeIdentifier(); } InodeIdentifier executableInode() const { return m_executable ? m_executable->inode : InodeIdentifier(); } + size_t number_of_open_file_descriptors() const; + private: friend class MemoryManager; friend bool scheduleNewProcess(); @@ -164,7 +164,7 @@ private: DWORD m_wakeupTime { 0 }; TSS32 m_tss; Descriptor* m_ldtEntries { nullptr }; - Vector> m_fileHandles; + Vector> m_file_descriptors; RingLevel m_ring { Ring0 }; int m_error { 0 }; void* m_kernelStack { nullptr }; @@ -172,7 +172,7 @@ private: pid_t m_waitee { -1 }; int m_waiteeStatus { 0 }; int m_fdBlockedOnRead { -1 }; - size_t m_maxFileHandles { 16 }; + size_t m_max_open_file_descriptors { 16 }; RetainPtr m_cwd; RetainPtr m_executable;