Browse Source

Kernel: Port sleep to ThreadBlocker

Robin Burchell 6 years ago
parent
commit
32fcfb79e9
4 changed files with 30 additions and 20 deletions
  1. 6 6
      Kernel/Process.cpp
  2. 10 4
      Kernel/Scheduler.cpp
  3. 4 5
      Kernel/Thread.cpp
  4. 10 5
      Kernel/Thread.h

+ 6 - 6
Kernel/Process.cpp

@@ -1289,10 +1289,10 @@ int Process::sys$usleep(useconds_t usec)
     if (!usec)
         return 0;
 
-    current->sleep(usec / 1000);
-    if (current->m_wakeup_time > g_uptime) {
+    u64 wakeup_time = current->sleep(usec / 1000);
+    if (wakeup_time > g_uptime) {
         ASSERT(current->m_was_interrupted_while_blocked);
-        u32 ticks_left_until_original_wakeup_time = current->m_wakeup_time - g_uptime;
+        u32 ticks_left_until_original_wakeup_time = wakeup_time - g_uptime;
         return ticks_left_until_original_wakeup_time / TICKS_PER_SECOND;
     }
     return 0;
@@ -1302,10 +1302,10 @@ int Process::sys$sleep(unsigned seconds)
 {
     if (!seconds)
         return 0;
-    current->sleep(seconds * TICKS_PER_SECOND);
-    if (current->m_wakeup_time > g_uptime) {
+    u64 wakeup_time = current->sleep(seconds * TICKS_PER_SECOND);
+    if (wakeup_time > g_uptime) {
         ASSERT(current->m_was_interrupted_while_blocked);
-        u32 ticks_left_until_original_wakeup_time = current->m_wakeup_time - g_uptime;
+        u32 ticks_left_until_original_wakeup_time = wakeup_time - g_uptime;
         return ticks_left_until_original_wakeup_time / TICKS_PER_SECOND;
     }
     return 0;

+ 10 - 4
Kernel/Scheduler.cpp

@@ -133,6 +133,16 @@ bool Thread::ThreadBlockerCondition::should_unblock(time_t, long)
     return m_block_until_condition();
 }
 
+Thread::ThreadBlockerSleep::ThreadBlockerSleep(u64 wakeup_time)
+    : m_wakeup_time(wakeup_time)
+{
+}
+
+bool Thread::ThreadBlockerSleep::should_unblock(time_t, long)
+{
+    return m_wakeup_time <= g_uptime;
+}
+
 // Called by the scheduler on threads that are blocked for some reason.
 // Make a decision as to whether to unblock them or not.
 void Thread::consider_unblock(time_t now_sec, long now_usec)
@@ -152,10 +162,6 @@ void Thread::consider_unblock(time_t now_sec, long now_usec)
     case Thread::BlockedSignal:
         /* don't know, don't care */
         return;
-    case Thread::BlockedSleep:
-        if (wakeup_time() <= g_uptime)
-            unblock();
-        return;
     case Thread::BlockedWait:
         process.for_each_child([&](Process& child) {
             if (waitee_pid() != -1 && waitee_pid() != child.pid())

+ 4 - 5
Kernel/Thread.cpp

@@ -135,11 +135,12 @@ void Thread::block(ThreadBlocker& blocker)
     block(Thread::BlockedCondition);
 }
 
-void Thread::sleep(u32 ticks)
+u64 Thread::sleep(u32 ticks)
 {
     ASSERT(state() == Thread::Running);
-    current->set_wakeup_time(g_uptime + ticks);
-    current->block(Thread::BlockedSleep);
+    u64 wakeup_time = g_uptime + ticks;
+    current->block(*new Thread::ThreadBlockerSleep(wakeup_time));
+    return wakeup_time;
 }
 
 const char* to_string(Thread::State state)
@@ -161,8 +162,6 @@ const char* to_string(Thread::State state)
         return "Skip1";
     case Thread::Skip0SchedulerPasses:
         return "Skip0";
-    case Thread::BlockedSleep:
-        return "Sleep";
     case Thread::BlockedWait:
         return "Wait";
     case Thread::BlockedSignal:

+ 10 - 5
Kernel/Thread.h

@@ -65,7 +65,6 @@ public:
 
         __Begin_Blocked_States__,
         BlockedLurking,
-        BlockedSleep,
         BlockedWait,
         BlockedSignal,
         BlockedSelect,
@@ -127,6 +126,15 @@ public:
         Function<bool()> m_block_until_condition;
     };
 
+    class ThreadBlockerSleep : public ThreadBlocker {
+    public:
+        ThreadBlockerSleep(u64 wakeup_time);
+        virtual bool should_unblock(time_t, long) override;
+
+    private:
+        u64 m_wakeup_time { 0 };
+    };
+
     void did_schedule() { ++m_times_scheduled; }
     u32 times_scheduled() const { return m_times_scheduled; }
 
@@ -146,13 +154,11 @@ public:
     u32 ticks() const { return m_ticks; }
     pid_t waitee_pid() const { return m_waitee_pid; }
 
-    void sleep(u32 ticks);
+    u64 sleep(u32 ticks);
     void block(Thread::State);
     void block(ThreadBlocker& blocker);
     void unblock();
 
-    void set_wakeup_time(u64 t) { m_wakeup_time = t; }
-    u64 wakeup_time() const { return m_wakeup_time; }
     void block_until(Function<bool()>&&);
     KResult wait_for_connect(FileDescription&);
 
@@ -226,7 +232,6 @@ private:
     FarPtr m_far_ptr;
     u32 m_ticks { 0 };
     u32 m_ticks_left { 0 };
-    u64 m_wakeup_time { 0 };
     u32 m_times_scheduled { 0 };
     u32 m_pending_signals { 0 };
     u32 m_signal_mask { 0 };