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;