소스 검색

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.
Andreas Kling 6 년 전
부모
커밋
065f0aee35
4개의 변경된 파일37개의 추가작업 그리고 18개의 파일을 삭제
  1. 11 0
      AK/Vector.h
  2. 1 1
      Kernel/ProcFileSystem.cpp
  3. 21 13
      Kernel/Process.cpp
  4. 4 4
      Kernel/Process.h

+ 11 - 0
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; }

+ 1 - 1
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());
     }

+ 21 - 13
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;
 }
 

+ 4 - 4
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<OwnPtr<FileHandle>> m_fileHandles;
+    Vector<OwnPtr<FileHandle>> 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<VirtualFileSystem::Node> m_cwd;
     RetainPtr<VirtualFileSystem::Node> m_executable;