Răsfoiți Sursa

fix tuple and rbtree, simplify kernel process

fix std::map at(): return reference to T
fix std::get(tuple&&): return lvalue reference if Type is lval ref
fix rbtree: operator bool() should be non-explicit
fix rbtree: add a 4-bytes member to rbtree to keep it aligned to 16bytes
process: remove next_pid
process: changed some shitty constructors
process, syscall, vfs: change format of some container calls
greatbridf 1 an în urmă
părinte
comite
0a7b5413a5

+ 7 - 6
gblibstdc++/include/bits/rbtree

@@ -236,7 +236,7 @@ struct rbtree {
         { p = p->prev(); return *this; }
         constexpr _iterator operator--(int)
         { _iterator ret(p); (void)this->operator--(); return ret; }
-        explicit constexpr operator bool(void)
+        constexpr operator bool(void)
         { return p; }
         constexpr operator _iterator<true>()
         { return _iterator<true> { p }; }
@@ -250,9 +250,9 @@ struct rbtree {
     using node_alloc_traits = std::allocator_traits<node_allocator>;
 
     node* root;
+    node_allocator alloc;
     std::size_t _size;
     Compare comp;
-    node_allocator alloc;
 
 private:
     template <typename... Args>
@@ -316,7 +316,7 @@ public:
     }
 
     explicit constexpr rbtree(const Compare& comp, const node_allocator& alloc)
-        : root(), _size(), comp(comp), alloc(alloc) {}
+        : root(), alloc(alloc), _size(), comp(comp) {}
 
     constexpr rbtree(const rbtree& other)
         : rbtree(other.comp, other.alloc)
@@ -336,13 +336,14 @@ public:
     
     constexpr rbtree(rbtree&& other) noexcept
         : root(std::exchange(other.root, nullptr))
+        , alloc(std::move(other.alloc))
         , _size(std::exchange(other._size, 0))
-        , comp(std::move(other.comp)), alloc(std::move(other.alloc)) {}
+        , comp(std::move(other.comp)) {}
 
     constexpr rbtree(rbtree&& other, const node_allocator& alloc) noexcept
         : root(std::exchange(other.root, nullptr))
-        , _size(std::exchange(other._size, 0))
-        , comp(std::move(other.comp)), alloc(alloc) {}
+        , alloc(alloc) , _size(std::exchange(other._size, 0))
+        , comp(std::move(other.comp)) {}
     
     constexpr ~rbtree() { destroy(); }
 

+ 2 - 2
gblibstdc++/include/map

@@ -137,13 +137,13 @@ public:
     // the specified key, it should throw an exception
     // TODO: exceptions
     __GBLIBCPP_CONSTEXPR
-    T& at(const Key& key) { return *find(key); }
+    T& at(const Key& key) { return find(key)->second; }
 
     // if the container does not have an element with
     // the specified key, it should throw an exception
     // TODO: exceptions
     __GBLIBCPP_CONSTEXPR
-    const T& at(const Key& key) const { return *find(key); }
+    const T& at(const Key& key) const { return find(key)->second; }
 
     __GBLIBCPP_CONSTEXPR
     std::pair<iterator, bool> insert(const value_type& value)

+ 10 - 6
gblibstdc++/include/tuple

@@ -136,18 +136,22 @@ class tuple_impl<I, Type, Types...> {
     constexpr auto&& _getr(void)
     {
         if constexpr (I == J)
-            return std::move(val);
+            return std::forward<Type>(val);
         else
-            return std::move(next.template _getr<J>());
+            return std::forward<
+                decltype(next.template _getr<J>())>(
+                    next.template _getr<J>());
     }
 
     template <std::size_t J>
     constexpr const auto&& _getr(void) const
     {
         if constexpr (I == J)
-            return std::move(val);
+            return std::forward<Type>(val);
         else
-            return std::move(next.template _getr<J>());
+            return std::forward<
+                decltype(next.template _getr<J>())>(
+                    next.template _getr<J>());
     }
 
 public:
@@ -211,13 +215,13 @@ class tuple_impl<I, Type> {
     constexpr Type&& _getr(void)
     {
         static_assert(J == I);
-        return std::move(val);
+        return std::forward<Type>(val);
     }
     template <std::size_t J>
     constexpr Type const&& _getr(void) const
     {
         static_assert(J == I);
-        return std::move(val);
+        return std::forward<Type>(val);
     }
 
 public:

+ 44 - 37
include/kernel/process.hpp

@@ -194,9 +194,7 @@ public:
         constexpr filearr& operator=(filearr&&) = delete;
         constexpr filearr(void) = default;
         constexpr filearr(filearr&& val)
-            : arr { std::move(val.arr) }
-        {
-        }
+            : arr { std::move(val.arr) } { }
 
         constexpr int dup(int old_fd)
         {
@@ -216,7 +214,7 @@ public:
 
             auto [ _, iter_file ] = *iter;
 
-            this->arr.insert(std::make_pair(new_fd, iter_file));
+            this->arr.emplace(new_fd, iter_file);
             ++iter_file->ref;
             return new_fd;
         }
@@ -224,7 +222,7 @@ public:
         constexpr void dup_all(const filearr& orig)
         {
             for (auto [ fd, iter_file ] : orig.arr) {
-                this->arr.insert(std::make_pair(fd, iter_file));
+                this->arr.emplace(fd, iter_file);
                 ++iter_file->ref;
             }
         }
@@ -253,8 +251,12 @@ public:
                     .write = 0,
                 },
             });
+
+            bool inserted = false;
             int fd = _next_fd();
-            arr.insert(std::make_pair(fd, iter));
+            std::tie(std::ignore, inserted) =
+                arr.insert(std::make_pair(fd, iter));
+            assert(inserted);
 
             // TODO: use copy_to_user()
             pipefd[0] = fd;
@@ -271,7 +273,8 @@ public:
                 },
             });
             fd = _next_fd();
-            arr.insert(std::make_pair(fd, iter));
+            std::tie(std::ignore, inserted) = arr.emplace(fd, iter);
+            assert(inserted);
 
             // TODO: use copy_to_user()
             pipefd[1] = fd;
@@ -308,23 +311,26 @@ public:
             });
 
             int fd = _next_fd();
-            arr.insert(std::make_pair(fd, iter));
+            auto [ _, inserted ] = arr.emplace(fd, iter);
+            assert(inserted);
             return fd;
         }
 
         constexpr void close(int fd)
         {
             auto iter = arr.find(fd);
-            if (iter) {
-                _close(iter->second);
-                arr.erase(iter);
-            }
+            if (!iter)
+                return;
+
+            _close(iter->second);
+            arr.erase(iter);
         }
 
         constexpr void close_all(void)
         {
             for (auto&& [ fd, file ] : arr)
-                close(fd);
+                _close(file);
+            arr.clear();
         }
 
         constexpr ~filearr()
@@ -376,24 +382,16 @@ public:
             current_process = this;
     }
 
-    process(const process&);
+    explicit process(const process& parent, pid_t pid);
 
     // this function is used for system initialization
     // DO NOT use this after the system is on
-    explicit process(pid_t ppid);
+    explicit process(pid_t pid, pid_t ppid);
 
     constexpr bool is_system(void) const
     { return attr.system; }
     constexpr bool is_zombie(void) const
     { return attr.zombie; }
-
-private:
-    static inline pid_t max_pid;
-
-    static inline pid_t alloc_pid(void)
-    {
-        return ++max_pid;
-    }
 };
 
 class proclist final {
@@ -404,26 +402,35 @@ public:
 
 private:
     list_type m_procs;
+    pid_t m_nextpid = 1;
+
+    constexpr pid_t next_pid() { return m_nextpid++; }
 
 public:
-    template <typename... Args>
-    iterator emplace(Args&&... args)
+    process& emplace(pid_t ppid)
     {
-        process _proc(std::forward<Args>(args)...);
-        auto pid = _proc.pid;
-        auto ppid = _proc.ppid;
-        auto [ iter, inserted ] =
-            m_procs.insert(std::make_pair(pid, std::move(_proc)));
-        
+        pid_t pid = next_pid();
+        auto [ iter, inserted ] = m_procs.try_emplace(pid, pid, ppid);
         assert(inserted);
 
-        if (ppid) {
+        if (try_find(ppid)) {
             bool success = false;
-            std::tie(std::ignore, success) = find(ppid).children.insert(pid);
+            std::tie(std::ignore, success) =
+                find(ppid).children.insert(pid);
             assert(success);
         }
 
-        return iter;
+        return iter->second;
+    }
+
+    process& copy_from(process& proc)
+    {
+        pid_t pid = next_pid();
+        auto [ iter, inserted ] = m_procs.try_emplace(pid, proc, pid);
+        assert(inserted);
+
+        proc.children.insert(pid);
+        return iter->second;
     }
 
     constexpr void remove(pid_t pid)
@@ -439,13 +446,13 @@ public:
     }
 
     constexpr bool try_find(pid_t pid) const
-    { return !!m_procs.find(pid); }
+    { return m_procs.find(pid); }
 
     // if process doesn't exist, the behavior is undefined
     constexpr process& find(pid_t pid)
     {
         auto iter = m_procs.find(pid);
-        assert(!!iter);
+        assert(iter);
         return iter->second;
     }
 
@@ -471,7 +478,7 @@ public:
     // the process MUST exist, or the behavior is undefined
     void send_signal(pid_t pid, kernel::sig_t signal)
     {
-        auto proc = this->find(pid);
+        auto& proc = this->find(pid);
         proc.signals.set(signal);
     }
     void send_signal_grp(pid_t pgid, kernel::sig_t signal)

+ 18 - 18
src/kernel/process.cpp

@@ -92,15 +92,12 @@ void thread::free_kstack(uint32_t p)
     pkstack_bmp->clear(p);
 }
 
-process::process(const process& parent)
+process::process(const process& parent, pid_t pid)
     : mms { *kernel_mms }
-    , attr { .system = parent.is_system() }
-    , pwd { parent.pwd }
-    , signals { parent.signals }
-    , pid { process::alloc_pid() }
+    , attr { parent.attr } , pwd { parent.pwd }
+    , signals { parent.signals } , pid { pid }
     , ppid { parent.pid } , pgid { parent.pgid } , sid { parent.sid }
-    , control_tty { parent.control_tty }
-    , children {}
+    , control_tty { parent.control_tty } , children {}
 {
     for (auto& area : parent.mms) {
         if (area.is_kernel_space() || area.attr.in.system)
@@ -112,11 +109,11 @@ process::process(const process& parent)
     this->files.dup_all(parent.files);
 }
 
-process::process(pid_t ppid)
+process::process(pid_t pid, pid_t ppid)
     : mms(*kernel_mms)
     , attr { .system = true }
     , pwd { "/" }
-    , pid { process::alloc_pid() }
+    , pid { pid }
     , ppid { ppid }
     , pgid {} , sid {} , control_tty {}
     , children {} { }
@@ -217,10 +214,11 @@ void kernel_threadd_main(void)
 void NORETURN _kernel_init(void)
 {
     // pid 2 is kernel thread daemon
-    auto* proc = &procs->emplace(1)->second;
+    auto& proc = procs->emplace(1);
+    assert(proc.pid == 2);
 
     // create thread
-    thread thd(proc, true);
+    thread thd(&proc, true);
 
     auto* esp = &thd.esp;
 
@@ -237,7 +235,7 @@ void NORETURN _kernel_init(void)
     // eflags
     push_stack(esp, 0x200);
 
-    readythds->push(&proc->thds.Emplace(std::move(thd)));
+    readythds->push(&proc.thds.Emplace(std::move(thd)));
 
     // ------------------------------------------
 
@@ -324,17 +322,19 @@ void NORETURN init_scheduler(void)
     process::filearr::init_global_file_container();
 
     // init process has no parent
-    auto* init = &procs->emplace(0)->second;
-    init->files.open("/dev/console", O_RDONLY);
-    init->files.open("/dev/console", O_WRONLY);
-    init->files.open("/dev/console", O_WRONLY);
+    auto& init = procs->emplace(0);
+    assert(init.pid == 1);
+
+    init.files.open("/dev/console", O_RDONLY);
+    init.files.open("/dev/console", O_WRONLY);
+    init.files.open("/dev/console", O_WRONLY);
 
     // we need interrupts enabled for cow mapping so now we disable it
     // in case timer interrupt mess things up
     asm_cli();
 
-    current_process = init;
-    current_thread = &init->thds.Emplace(init, true);
+    current_process = &init;
+    current_thread = &init.thds.Emplace(&init, true);
     readythds->push(current_thread);
 
     tss.ss0 = KERNEL_DATA_SEGMENT;

+ 4 - 3
src/kernel/syscall.cpp

@@ -25,8 +25,9 @@ syscall_handler syscall_handlers[SYSCALL_HANDLERS_SIZE];
 extern "C" void _syscall_stub_fork_return(void);
 int _syscall_fork(interrupt_stack* data)
 {
-    auto* newproc = &procs->emplace(*current_process)->second;
-    auto* newthd = &newproc->thds.Emplace(*current_thread, newproc);
+    process& curproc = *current_process;
+    auto& newproc = procs->copy_from(curproc);
+    auto* newthd = &newproc.thds.Emplace(*current_thread, &newproc);
     readythds->push(newthd);
 
     // create fake interrupt stack
@@ -61,7 +62,7 @@ int _syscall_fork(interrupt_stack* data)
     // eflags
     push_stack(&newthd->esp, 0);
 
-    return newproc->pid;
+    return newproc.pid;
 }
 
 int _syscall_write(interrupt_stack* data)

+ 2 - 2
src/kernel/vfs.cpp

@@ -122,7 +122,7 @@ fs::vfs::vfs(void)
 fs::inode* fs::vfs::cache_inode(inode_flags flags, uint32_t perm, size_t size, ino_t ino)
 {
     auto [ iter, inserted ] =
-        _inodes.insert(std::make_pair(ino, inode { flags, perm, ino, this, size }));
+        _inodes.try_emplace(ino, inode { flags, perm, ino, this, size });
     return &iter->second;
 }
 fs::inode* fs::vfs::get_inode(ino_t ino)
@@ -233,8 +233,8 @@ private:
     using fdata_t = vector<char>;
 
 private:
-    fs::ino_t _next_ino;
     std::map<fs::ino_t, void*> inode_data;
+    fs::ino_t _next_ino;
 
 private:
     fs::ino_t _assign_ino(void)