[haiku-commits] haiku: hrev53374 - src/system/kernel

  • From: waddlesplash <waddlesplash@xxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 14 Aug 2019 17:28:22 -0400 (EDT)

hrev53374 adds 1 changeset to branch 'master'
old head: 31d70c106be1a8f0f0b50dba3a5020adf6421147
new head: 8c6b1519a2b58a59c337df69c2d38514f3aa750f
overview: 
https://git.haiku-os.org/haiku/log/?qt=range&q=8c6b1519a2b5+%5E31d70c106be1

----------------------------------------------------------------------------

8c6b1519a2b5: kernel/daemon: Sleep as long as possible between runs.
  
  Avoids waking up every 100ms to do nothing.
  
  Change-Id: I48c7be41f6102a76b7e770ea45c665ab991c79f0
  Reviewed-on: https://review.haiku-os.org/c/haiku/+/1700
  Reviewed-by: waddlesplash <waddlesplash@xxxxxxxxx>

                              [ Augustin Cavalier <waddlesplash@xxxxxxxxx> ]

----------------------------------------------------------------------------

Revision:    hrev53374
Commit:      8c6b1519a2b58a59c337df69c2d38514f3aa750f
URL:         https://git.haiku-os.org/haiku/commit/?id=8c6b1519a2b5
Author:      Augustin Cavalier <waddlesplash@xxxxxxxxx>
Date:        Sat Aug 10 17:51:41 2019 UTC
Committer:   waddlesplash <waddlesplash@xxxxxxxxx>
Commit-Date: Wed Aug 14 21:28:20 2019 UTC

----------------------------------------------------------------------------

1 file changed, 24 insertions(+), 30 deletions(-)
src/system/kernel/kernel_daemon.cpp | 54 +++++++++++++++------------------

----------------------------------------------------------------------------

diff --git a/src/system/kernel/kernel_daemon.cpp 
b/src/system/kernel/kernel_daemon.cpp
index fbc7a2cae3..5c1f7cdb79 100644
--- a/src/system/kernel/kernel_daemon.cpp
+++ b/src/system/kernel/kernel_daemon.cpp
@@ -17,17 +17,11 @@
 #include <util/DoublyLinkedList.h>
 
 
-// The use of snooze() in the kernel_daemon() function is very inaccurate, of
-// course - the time the daemons need to execute add up in each iteration.
-// But since the kernel daemon is documented to be very inaccurate, this
-// actually might be okay (and that's why it's implemented this way now :-).
-// BeOS R5 seems to do it in the same way, anyway.
-
 struct daemon : DoublyLinkedListLinkImpl<struct daemon> {
        daemon_hook     function;
        void*           arg;
        int32           frequency;
-       int32           offset;
+       bigtime_t       last;
        bool            executing;
 };
 
@@ -54,6 +48,7 @@ private:
 private:
                        recursive_lock          fLock;
                        DaemonList                      fDaemons;
+                       sem_id                          fDaemonAddedSem;
                        thread_id                       fThread;
                        ConditionVariable       fUnregisterCondition;
                        int32                           fUnregisterWaiters;
@@ -69,6 +64,10 @@ KernelDaemon::Init(const char* name)
 {
        recursive_lock_init(&fLock, name);
 
+       fDaemonAddedSem = create_sem(0, "kernel daemon added");
+       if (fDaemonAddedSem < 0)
+               return fDaemonAddedSem;
+
        fThread = spawn_kernel_thread(&_DaemonThreadEntry, name, B_LOW_PRIORITY,
                this);
        if (fThread < 0)
@@ -94,27 +93,14 @@ KernelDaemon::Register(daemon_hook function, void* arg, int 
frequency)
        daemon->function = function;
        daemon->arg = arg;
        daemon->frequency = frequency;
+       daemon->last = 0;
        daemon->executing = false;
 
-       RecursiveLocker _(fLock);
-
-       if (frequency > 1) {
-               // we try to balance the work-load for each daemon run
-               // (beware, it's a very simple algorithm, yet effective)
-
-               DaemonList::Iterator iterator = fDaemons.GetIterator();
-               int32 num = 0;
-
-               while (iterator.HasNext()) {
-                       if (iterator.Next()->frequency == frequency)
-                               num++;
-               }
-
-               daemon->offset = num % frequency;
-       } else
-               daemon->offset = 0;
-
+       RecursiveLocker locker(fLock);
        fDaemons.Add(daemon);
+       locker.Unlock();
+
+       release_sem(fDaemonAddedSem);
        return B_OK;
 }
 
@@ -218,20 +204,29 @@ status_t
 KernelDaemon::_DaemonThread()
 {
        struct daemon marker;
-       int32 iteration = 0;
+       const bigtime_t start = system_time(), iterationToUsecs = 100 * 1000;
 
        marker.arg = NULL;
 
        while (true) {
                RecursiveLocker locker(fLock);
 
+               bigtime_t timeout = INT64_MAX;
+
                // iterate through the list and execute each daemon if needed
                while (struct daemon* daemon = _NextDaemon(marker)) {
                        daemon->executing = true;
                        locker.Unlock();
 
-                       if (((iteration + daemon->offset) % daemon->frequency) 
== 0)
-                               daemon->function(daemon->arg, iteration);
+                       const bigtime_t time = system_time();
+                       bigtime_t next = (daemon->last +
+                               (daemon->frequency * iterationToUsecs)) - time;
+                       if (next <= 0) {
+                               daemon->last = time;
+                               next = daemon->frequency * iterationToUsecs;
+                               daemon->function(daemon->arg, (time - start) / 
iterationToUsecs);
+                       }
+                       timeout = min_c(timeout, next);
 
                        locker.Lock();
                        daemon->executing = false;
@@ -244,8 +239,7 @@ KernelDaemon::_DaemonThread()
 
                locker.Unlock();
 
-               iteration++;
-               snooze(100000); // 0.1 seconds
+               acquire_sem_etc(fDaemonAddedSem, 1, B_RELATIVE_TIMEOUT, 
timeout);
        }
 
        return B_OK;


Other related posts:

  • » [haiku-commits] haiku: hrev53374 - src/system/kernel - waddlesplash