* kernel_daemon is now a C++ file, and uses DoublyLinkedList instead of
the C list mechanism which also makes the code nicer. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25375 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,12 +1,17 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2003-2008, Axel Dörfler, [email protected]. All rights reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
#ifndef _KERNEL_DAEMON_H
|
#ifndef _KERNEL_DAEMON_H
|
||||||
#define _KERNEL_DAEMON_H
|
#define _KERNEL_DAEMON_H
|
||||||
/*
|
|
||||||
** Copyright 2003, Axel Dörfler, [email protected]. All rights reserved.
|
|
||||||
** Distributed under the terms of the OpenBeOS License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <OS.h>
|
#include <OS.h>
|
||||||
|
|
||||||
extern status_t kernel_daemon_init(void);
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
#endif
|
||||||
|
status_t kernel_daemon_init(void);
|
||||||
|
|
||||||
#endif /* _KRENEL_DAEMON_H */
|
#endif /* _KRENEL_DAEMON_H */
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ KernelMergeObject kernel_core.o :
|
|||||||
heap.cpp
|
heap.cpp
|
||||||
image.c
|
image.c
|
||||||
int.c
|
int.c
|
||||||
kernel_daemon.c
|
kernel_daemon.cpp
|
||||||
linkhack.c
|
linkhack.c
|
||||||
lock.cpp
|
lock.cpp
|
||||||
main.c
|
main.c
|
||||||
|
|||||||
@@ -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.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <KernelExport.h>
|
|
||||||
#include <signal.h>
|
|
||||||
|
|
||||||
#include <kernel_daemon.h>
|
#include <kernel_daemon.h>
|
||||||
#include <lock.h>
|
|
||||||
#include <util/list.h>
|
|
||||||
|
|
||||||
|
#include <new>
|
||||||
|
#include <signal.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <KernelExport.h>
|
||||||
|
|
||||||
|
#include <lock.h>
|
||||||
|
#include <util/AutoLock.h>
|
||||||
|
#include <util/DoublyLinkedList.h>
|
||||||
|
|
||||||
|
|
||||||
// The use of snooze() in the kernel_daemon() function is very inaccurate, of
|
// 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.
|
// 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 :-).
|
// 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.
|
// BeOS R5 seems to do it in the same way, anyway.
|
||||||
|
|
||||||
|
struct daemon : DoublyLinkedListLinkImpl<struct daemon> {
|
||||||
struct daemon {
|
|
||||||
list_link link;
|
|
||||||
daemon_hook function;
|
daemon_hook function;
|
||||||
void *arg;
|
void* arg;
|
||||||
int32 frequency;
|
int32 frequency;
|
||||||
int32 offset;
|
int32 offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef DoublyLinkedList<struct daemon> DaemonList;
|
||||||
|
|
||||||
static mutex sDaemonMutex;
|
static mutex sDaemonMutex;
|
||||||
static struct list sDaemons;
|
static DaemonList sDaemons;
|
||||||
|
|
||||||
|
|
||||||
static int32
|
static status_t
|
||||||
kernel_daemon(void *data)
|
kernel_daemon(void* data)
|
||||||
{
|
{
|
||||||
int32 iteration = 0;
|
int32 iteration = 0;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
struct daemon *daemon = NULL;
|
|
||||||
|
|
||||||
mutex_lock(&sDaemonMutex);
|
mutex_lock(&sDaemonMutex);
|
||||||
|
|
||||||
|
DaemonList::Iterator iterator = sDaemons.GetIterator();
|
||||||
|
|
||||||
// iterate through the list and execute each daemon if needed
|
// 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)
|
if (((iteration + daemon->offset) % daemon->frequency) == 0)
|
||||||
daemon->function(daemon->arg, iteration);
|
daemon->function(daemon->arg, iteration);
|
||||||
}
|
}
|
||||||
@@ -54,42 +59,44 @@ kernel_daemon(void *data)
|
|||||||
iteration++;
|
iteration++;
|
||||||
snooze(100000); // 0.1 seconds
|
snooze(100000); // 0.1 seconds
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
// #pragma mark -
|
||||||
unregister_kernel_daemon(daemon_hook function, void *arg)
|
|
||||||
{
|
|
||||||
struct daemon *daemon = NULL;
|
|
||||||
|
|
||||||
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
|
// 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) {
|
if (daemon->function == function && daemon->arg == arg) {
|
||||||
// found it!
|
// found it!
|
||||||
list_remove_item(&sDaemons, daemon);
|
iterator.Remove();
|
||||||
free(daemon);
|
free(daemon);
|
||||||
break;
|
return B_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mutex_unlock(&sDaemonMutex);
|
|
||||||
|
|
||||||
// if we've iterated through the whole list, we didn't
|
return B_ENTRY_NOT_FOUND;
|
||||||
// find the daemon, and "daemon" is NULL
|
|
||||||
return daemon != NULL ? B_OK : B_ENTRY_NOT_FOUND;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
extern "C" status_t
|
||||||
register_kernel_daemon(daemon_hook function, void *arg, int frequency)
|
register_kernel_daemon(daemon_hook function, void* arg, int frequency)
|
||||||
{
|
{
|
||||||
struct daemon *daemon;
|
|
||||||
|
|
||||||
if (function == NULL || frequency < 1)
|
if (function == NULL || frequency < 1)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
daemon = malloc(sizeof(struct daemon));
|
struct daemon* daemon = new(std::nothrow) struct daemon();
|
||||||
if (daemon == NULL)
|
if (daemon == NULL)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
@@ -97,17 +104,17 @@ register_kernel_daemon(daemon_hook function, void *arg, int frequency)
|
|||||||
daemon->arg = arg;
|
daemon->arg = arg;
|
||||||
daemon->frequency = frequency;
|
daemon->frequency = frequency;
|
||||||
|
|
||||||
mutex_lock(&sDaemonMutex);
|
MutexLocker _(sDaemonMutex);
|
||||||
|
|
||||||
if (frequency > 1) {
|
if (frequency > 1) {
|
||||||
// we try to balance the work-load for each daemon run
|
// we try to balance the work-load for each daemon run
|
||||||
// (beware, it's a very simple algorithm, yet effective)
|
// (beware, it's a very simple algorithm, yet effective)
|
||||||
|
|
||||||
struct daemon *d = NULL;
|
DaemonList::Iterator iterator = sDaemons.GetIterator();
|
||||||
int32 num = 0;
|
int32 num = 0;
|
||||||
|
|
||||||
while ((d = list_get_next_item(&sDaemons, d)) != NULL) {
|
while (iterator.HasNext()) {
|
||||||
if (d->frequency == frequency)
|
if (iterator.Next()->frequency == frequency)
|
||||||
num++;
|
num++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,23 +122,21 @@ register_kernel_daemon(daemon_hook function, void *arg, int frequency)
|
|||||||
} else
|
} else
|
||||||
daemon->offset = 0;
|
daemon->offset = 0;
|
||||||
|
|
||||||
list_add_item(&sDaemons, daemon);
|
sDaemons.Add(daemon);
|
||||||
mutex_unlock(&sDaemonMutex);
|
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
extern "C" status_t
|
||||||
kernel_daemon_init(void)
|
kernel_daemon_init(void)
|
||||||
{
|
{
|
||||||
thread_id thread;
|
thread_id thread;
|
||||||
|
|
||||||
mutex_init(&sDaemonMutex, "kernel daemon");
|
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);
|
send_signal_etc(thread, SIGCONT, B_DO_NOT_RESCHEDULE);
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
Reference in New Issue
Block a user