diff --git a/headers/private/kernel/kernel_daemon.h b/headers/private/kernel/kernel_daemon.h index 2269f00963..978410acf2 100644 --- a/headers/private/kernel/kernel_daemon.h +++ b/headers/private/kernel/kernel_daemon.h @@ -1,12 +1,17 @@ +/* + * Copyright 2003-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Distributed under the terms of the MIT License. + */ #ifndef _KERNEL_DAEMON_H #define _KERNEL_DAEMON_H -/* -** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved. -** Distributed under the terms of the OpenBeOS License. -*/ + #include -extern status_t kernel_daemon_init(void); + +#ifdef __cplusplus +extern "C" +#endif +status_t kernel_daemon_init(void); #endif /* _KRENEL_DAEMON_H */ diff --git a/src/system/kernel/Jamfile b/src/system/kernel/Jamfile index 7c0f0c13e2..2765b23d71 100644 --- a/src/system/kernel/Jamfile +++ b/src/system/kernel/Jamfile @@ -25,7 +25,7 @@ KernelMergeObject kernel_core.o : heap.cpp image.c int.c - kernel_daemon.c + kernel_daemon.cpp linkhack.c lock.cpp main.c diff --git a/src/system/kernel/kernel_daemon.c b/src/system/kernel/kernel_daemon.cpp similarity index 58% rename from src/system/kernel/kernel_daemon.c rename to src/system/kernel/kernel_daemon.cpp index 34dc1817f0..41e60c7179 100644 --- a/src/system/kernel/kernel_daemon.c +++ b/src/system/kernel/kernel_daemon.cpp @@ -1,18 +1,21 @@ /* - * Copyright 2003-2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Copyright 2003-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved. * Distributed under the terms of the MIT License. */ -#include -#include - #include -#include -#include +#include +#include #include +#include + +#include +#include +#include + // 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. @@ -20,32 +23,34 @@ // 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 { - list_link link; +struct daemon : DoublyLinkedListLinkImpl { daemon_hook function; - void *arg; + void* arg; int32 frequency; int32 offset; }; +typedef DoublyLinkedList DaemonList; + static mutex sDaemonMutex; -static struct list sDaemons; +static DaemonList sDaemons; -static int32 -kernel_daemon(void *data) +static status_t +kernel_daemon(void* data) { int32 iteration = 0; while (true) { - struct daemon *daemon = NULL; - mutex_lock(&sDaemonMutex); + DaemonList::Iterator iterator = sDaemons.GetIterator(); + // iterate through the list and execute each daemon if needed - while ((daemon = list_get_next_item(&sDaemons, daemon)) != NULL) { + while (iterator.HasNext()) { + struct daemon* daemon = iterator.Next(); + if (((iteration + daemon->offset) % daemon->frequency) == 0) daemon->function(daemon->arg, iteration); } @@ -54,42 +59,44 @@ kernel_daemon(void *data) iteration++; snooze(100000); // 0.1 seconds } + + return B_OK; } -status_t -unregister_kernel_daemon(daemon_hook function, void *arg) -{ - struct daemon *daemon = NULL; +// #pragma mark - - mutex_lock(&sDaemonMutex); + +extern "C" status_t +unregister_kernel_daemon(daemon_hook function, void* arg) +{ + MutexLocker _(sDaemonMutex); + + DaemonList::Iterator iterator = sDaemons.GetIterator(); // search for the daemon and remove it from the list - while ((daemon = list_get_next_item(&sDaemons, daemon)) != NULL) { + while (iterator.HasNext()) { + struct daemon* daemon = iterator.Next(); + if (daemon->function == function && daemon->arg == arg) { // found it! - list_remove_item(&sDaemons, daemon); + iterator.Remove(); free(daemon); - break; + return B_OK; } } - mutex_unlock(&sDaemonMutex); - // if we've iterated through the whole list, we didn't - // find the daemon, and "daemon" is NULL - return daemon != NULL ? B_OK : B_ENTRY_NOT_FOUND; + return B_ENTRY_NOT_FOUND; } -status_t -register_kernel_daemon(daemon_hook function, void *arg, int frequency) +extern "C" status_t +register_kernel_daemon(daemon_hook function, void* arg, int frequency) { - struct daemon *daemon; - if (function == NULL || frequency < 1) return B_BAD_VALUE; - daemon = malloc(sizeof(struct daemon)); + struct daemon* daemon = new(std::nothrow) struct daemon(); if (daemon == NULL) return B_NO_MEMORY; @@ -97,17 +104,17 @@ register_kernel_daemon(daemon_hook function, void *arg, int frequency) daemon->arg = arg; daemon->frequency = frequency; - mutex_lock(&sDaemonMutex); + MutexLocker _(sDaemonMutex); if (frequency > 1) { // we try to balance the work-load for each daemon run // (beware, it's a very simple algorithm, yet effective) - struct daemon *d = NULL; + DaemonList::Iterator iterator = sDaemons.GetIterator(); int32 num = 0; - while ((d = list_get_next_item(&sDaemons, d)) != NULL) { - if (d->frequency == frequency) + while (iterator.HasNext()) { + if (iterator.Next()->frequency == frequency) num++; } @@ -115,23 +122,21 @@ register_kernel_daemon(daemon_hook function, void *arg, int frequency) } else daemon->offset = 0; - list_add_item(&sDaemons, daemon); - mutex_unlock(&sDaemonMutex); - + sDaemons.Add(daemon); return B_OK; } -status_t +extern "C" status_t kernel_daemon_init(void) { thread_id thread; mutex_init(&sDaemonMutex, "kernel daemon"); + new(&sDaemons) DaemonList; - list_init(&sDaemons); - - thread = spawn_kernel_thread(&kernel_daemon, "kernel daemon", B_LOW_PRIORITY, NULL); + thread = spawn_kernel_thread(&kernel_daemon, "kernel daemon", + B_LOW_PRIORITY, NULL); send_signal_etc(thread, SIGCONT, B_DO_NOT_RESCHEDULE); return B_OK;