Browse Source

Kernel: Port process groups to SpinLockProtectedValue

Andreas Kling 3 years ago
parent
commit
d6667e4cb8
3 changed files with 35 additions and 26 deletions
  1. 0 1
      Kernel/Process.cpp
  2. 33 22
      Kernel/ProcessGroup.cpp
  3. 2 3
      Kernel/ProcessGroup.h

+ 0 - 1
Kernel/Process.cpp

@@ -76,7 +76,6 @@ UNMAP_AFTER_INIT void Process::initialize()
     g_modules = new HashMap<String, OwnPtr<Module>>;
 
     next_pid.store(0, AK::MemoryOrder::memory_order_release);
-    g_process_groups = new ProcessGroup::List();
 
     hostname().with_exclusive([&](auto& name) {
         name = "courage";

+ 33 - 22
Kernel/ProcessGroup.cpp

@@ -1,52 +1,63 @@
 /*
  * Copyright (c) 2020, the SerenityOS developers.
+ * Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
  *
  * SPDX-License-Identifier: BSD-2-Clause
  */
 
+#include <AK/Singleton.h>
 #include <Kernel/ProcessGroup.h>
 
 namespace Kernel {
 
-RecursiveSpinLock g_process_groups_lock;
-ProcessGroup::List* g_process_groups;
+static AK::Singleton<SpinLockProtectedValue<ProcessGroup::List>> s_process_groups;
+
+SpinLockProtectedValue<ProcessGroup::List>& process_groups()
+{
+    return *s_process_groups;
+}
 
 ProcessGroup::~ProcessGroup()
 {
-    ScopedSpinLock lock(g_process_groups_lock);
-    g_process_groups->remove(*this);
+    process_groups().with([&](auto& groups) {
+        groups.remove(*this);
+    });
 }
 
 RefPtr<ProcessGroup> ProcessGroup::create(ProcessGroupID pgid)
 {
     auto process_group = adopt_ref_if_nonnull(new (nothrow) ProcessGroup(pgid));
-    if (process_group) {
-        ScopedSpinLock lock(g_process_groups_lock);
-        g_process_groups->prepend(*process_group);
-    }
-
+    if (!process_group)
+        return {};
+    process_groups().with([&](auto& groups) {
+        groups.prepend(*process_group);
+    });
     return process_group;
 }
 
 RefPtr<ProcessGroup> ProcessGroup::find_or_create(ProcessGroupID pgid)
 {
-    ScopedSpinLock lock(g_process_groups_lock);
-
-    if (auto existing = from_pgid(pgid))
-        return existing.release_nonnull();
-
-    return create(pgid);
+    return process_groups().with([&](auto& groups) -> RefPtr<ProcessGroup> {
+        for (auto& group : groups) {
+            if (group.pgid() == pgid)
+                return &group;
+        }
+        auto process_group = adopt_ref_if_nonnull(new (nothrow) ProcessGroup(pgid));
+        if (process_group)
+            groups.prepend(*process_group);
+        return process_group;
+    });
 }
 
 RefPtr<ProcessGroup> ProcessGroup::from_pgid(ProcessGroupID pgid)
 {
-    ScopedSpinLock lock(g_process_groups_lock);
-
-    for (auto& group : *g_process_groups) {
-        if (group.pgid() == pgid)
-            return &group;
-    }
-    return nullptr;
+    return process_groups().with([&](auto& groups) -> RefPtr<ProcessGroup> {
+        for (auto& group : groups) {
+            if (group.pgid() == pgid)
+                return &group;
+        }
+        return nullptr;
+    });
 }
 
 }

+ 2 - 3
Kernel/ProcessGroup.h

@@ -9,7 +9,7 @@
 #include <AK/IntrusiveList.h>
 #include <AK/RefCounted.h>
 #include <AK/Weakable.h>
-#include <Kernel/Locking/SpinLock.h>
+#include <Kernel/Locking/SpinLockProtectedValue.h>
 #include <Kernel/UnixTypes.h>
 
 namespace Kernel {
@@ -43,7 +43,6 @@ public:
     using List = IntrusiveList<ProcessGroup, RawPtr<ProcessGroup>, &ProcessGroup::m_list_node>;
 };
 
-extern ProcessGroup::List* g_process_groups;
-extern RecursiveSpinLock g_process_groups_lock;
+SpinLockProtectedValue<ProcessGroup::List>& process_groups();
 
 }