Added a 50% work-in-progress (very few free time) generic Defered Procedure Call (DPC) kernel module.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19759 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -2,6 +2,7 @@ SubDir HAIKU_TOP src add-ons kernel generic ;
|
||||
|
||||
SubInclude HAIKU_TOP src add-ons kernel generic atomizer ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel generic block_io ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel generic dpc ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel generic fast_log ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel generic ide_adapter ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel generic locked_pool ;
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
SubDir HAIKU_TOP src add-ons kernel generic dpc ;
|
||||
|
||||
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||
|
||||
KernelAddon dpc :
|
||||
dpc.c
|
||||
;
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
/* Deferred Procedure Call support kernel module
|
||||
*
|
||||
* Copyright 2007, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Philippe Houdoin, [email protected]
|
||||
*/
|
||||
|
||||
#include <KernelExport.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <module.h>
|
||||
|
||||
// #include <dpc.h>
|
||||
|
||||
#define DPC_MODULE_NAME "generic/dpc/v1"
|
||||
|
||||
typedef void (*dpc_func) (void *arg);
|
||||
|
||||
typedef struct {
|
||||
module_info info;
|
||||
void * (*new_dpc_thread)(const char *name, long priority, int max_dpc);
|
||||
status_t (*delete_dpc_thread)(void *thread);
|
||||
status_t (*queue_dpc)(void *thread, dpc_func dpc_name, void *arg);
|
||||
} dpc_module_info;
|
||||
|
||||
// ----
|
||||
|
||||
typedef struct {
|
||||
dpc_func function;
|
||||
void *arg;
|
||||
} dpc;
|
||||
|
||||
typedef struct {
|
||||
thread_id thread;
|
||||
sem_id wakeup_sem;
|
||||
int max_dpc;
|
||||
spinlock lock;
|
||||
dpc list[1];
|
||||
// max_dpc - 1 follow
|
||||
} dpc_queue;
|
||||
|
||||
static int32
|
||||
dpc_thread(void *arg)
|
||||
{
|
||||
// TODO:
|
||||
// loop on acquire_sem(queue->wakeup_sem), exit on bad sem
|
||||
// inner loop: disable interrupt, find first slot not empty, empty it, restore interrupts
|
||||
// and call the dpc
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ----
|
||||
|
||||
static void *
|
||||
new_dpc_thread(const char *name, long priority, int max_dpc)
|
||||
{
|
||||
char str[64];
|
||||
dpc_queue *queue;
|
||||
int i;
|
||||
|
||||
queue = malloc(sizeof(dpc_queue) + (max_dpc - 1) * sizeof(dpc));
|
||||
if (!queue)
|
||||
return NULL;
|
||||
|
||||
queue->max_dpc = max_dpc;
|
||||
queue->lock = 0;
|
||||
for (i = 0; i < max_dpc; i++) {
|
||||
queue->list[i].function = NULL;
|
||||
queue->list[i].arg = NULL;
|
||||
}
|
||||
|
||||
sprintf(str, "%.*s_wakeup_sem", (int) sizeof(str) - 11, name);
|
||||
queue->wakeup_sem = create_sem(-1, str);
|
||||
set_sem_owner(queue->wakeup_sem, B_SYSTEM_TEAM);
|
||||
|
||||
queue->thread = spawn_kernel_thread(dpc_thread, name, priority, queue);
|
||||
if (queue->thread < 0) {
|
||||
delete_sem(queue->wakeup_sem);
|
||||
free(queue);
|
||||
return NULL;
|
||||
}
|
||||
resume_thread(queue->thread);
|
||||
|
||||
return queue;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
delete_dpc_thread(void *thread)
|
||||
{
|
||||
dpc_queue *queue = thread;
|
||||
status_t exit_value;
|
||||
|
||||
if (!queue)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
delete_sem(queue->wakeup_sem);
|
||||
wait_for_thread(queue->thread, &exit_value);
|
||||
free(queue);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
queue_dpc(void *thread, dpc_func function, void *arg)
|
||||
{
|
||||
dpc_queue *queue = thread;
|
||||
|
||||
if (!queue)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// TODO: acquire queue (spin)lock, find an empty slot, release lock and
|
||||
// wakup the thread (but be interrupt handler safe here: B_DO_NOT_RESCHEDULE flag!
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static status_t
|
||||
std_ops(int32 op, ...)
|
||||
{
|
||||
switch (op) {
|
||||
case B_MODULE_INIT:
|
||||
return B_OK;
|
||||
case B_MODULE_UNINIT:
|
||||
return B_OK;
|
||||
|
||||
default:
|
||||
return B_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
static dpc_module_info sDPCModule = {
|
||||
{
|
||||
DPC_MODULE_NAME,
|
||||
0,
|
||||
std_ops
|
||||
},
|
||||
|
||||
new_dpc_thread,
|
||||
delete_dpc_thread,
|
||||
queue_dpc
|
||||
};
|
||||
|
||||
|
||||
module_info *modules[] = {
|
||||
(module_info *) &sDPCModule,
|
||||
NULL
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user