Subversion Repositories shark

Compare Revisions

Ignore whitespace Rev 37 → Rev 38

/shark/trunk/kernel/init.c
18,24 → 18,16
 
/**
------------
CVS : $Id: init.c,v 1.1.1.1 2002-03-29 14:12:51 pj Exp $
CVS : $Id: init.c,v 1.2 2003-01-07 17:07:49 pj Exp $
 
File: $File$
Revision: $Revision: 1.1.1.1 $
Last update: $Date: 2002-03-29 14:12:51 $
Revision: $Revision: 1.2 $
Last update: $Date: 2003-01-07 17:07:49 $
------------
 
Kernel module registration and miscellaneous functions
- Kernel module registration functions
- miscellaneous functions related to module registration, system init and end
 
This file contains:
 
level_alloc_descriptor
resource_alloc_descriptor
__compute_args__
__call_main__
sys_atinit
sys_atexit
 
**/
 
/*
72,6 → 64,10
#include <kernel/var.h>
#include <kernel/func.h>
 
/***********************************************************************
* Runlevel management
***********************************************************************/
 
/*+ List of function to call at each rnlevel;
they are posted with sys_atrunlevel +*/
static struct exit_func {
199,23 → 195,177
return 0;
}
 
/***********************************************************************
* Level Default Descriptor
***********************************************************************/
 
static void level_excfunc(LEVEL l)
{
printk(KERN_EMERG "unreg scheduling function called, level=%d!\n", l);
kern_raise(XINVALID_TASK, exec_shadow);
}
 
static int level_return1(void) { return 1; }
static int level_returnminus1(void) { return -1; }
static void level_nothing(void) { }
static int level_return0(void) { return 0; }
 
static level_des level_default_descriptor =
{
(void (*)(LEVEL,PID,TASK_MODEL *))level_excfunc, /* private_insert */
(void (*)(LEVEL,PID)) level_excfunc, /* private_extract */
(int (*)(LEVEL,PID)) level_return0, /* private_eligible */
(void (*)(LEVEL,PID, int)) level_excfunc, /* private_dispatch */
(void (*)(LEVEL,PID)) level_excfunc, /* private_epilogue */
(PID (*)(LEVEL)) level_returnminus1, /* pubvlic_scheduler */
(int (*)(LEVEL,bandwidth_t *)) level_return1, /* public_guarantee */
(int (*)(LEVEL,PID,TASK_MODEL *))level_returnminus1, /* public_create */
(void (*)(LEVEL,PID)) level_nothing, /* public_detach */
(void (*)(LEVEL,PID)) level_excfunc, /* public_end */
(int (*)(LEVEL,PID)) level_return0, /* public_eligible */
(void (*)(LEVEL,PID, int)) level_excfunc, /* public_dispatch */
(void (*)(LEVEL,PID)) level_excfunc, /* public_epilogue */
(void (*)(LEVEL,PID)) level_excfunc, /* public_activate */
(void (*)(LEVEL,PID)) level_excfunc, /* public_unblock */
(void (*)(LEVEL,PID)) level_excfunc, /* public_block */
(int (*)(LEVEL,PID,void *)) level_excfunc, /* public_message */
};
 
 
/***********************************************************************
* Module registration
***********************************************************************/
 
/* this function initializes all the data structures used by the level
registration functions */
void levels_init(void)
{
int l;
for (l=0; l<MAX_SCHED_LEVEL; l++) {
level_table[l] = &level_default_descriptor;
level_used[l] = 0;
level_next[l] = l+1;
level_prev[l] = l-1;
}
 
level_next[MAX_SCHED_LEVEL-1l] = -1;
level_prev[0] = -1;
level_first = -1;
level_last = -1;
level_free = 0;
}
 
/*+ This function returns a level_des **. the value returned shall be
used to register a level module. The function shall be called only at
module registration time. It assume that the system is not yet
initialized, so we shall not call sys_abort... +*/
LEVEL level_alloc_descriptor()
used to register a level module.
 
The function is usually called at module registration time. The
function can also be called when the system is already started, to
allow the implementation of dynamic module registration.
 
The argument must be the size of the data block that have to be allocated
 
The function returns the number of the descriptor allocated for the module
or -1 in case there are no free descriptors.
 
The function also reserves a descriptor with size s, initialized
with default function pointers.
 
+*/
LEVEL level_alloc_descriptor(size_t s)
{
if (sched_levels == MAX_SCHED_LEVEL)
{
printk("Too many scheduling levels!!!\n");
l1_exit(1);
LEVEL l;
/* try to find a free descriptor */
if (level_free == -1)
return -1;
 
/* alloc it */
l = level_free;
level_free = level_next[l];
 
level_used[l] = 1;
 
/* insert the module as the last in the scheduling module's list */
if (level_last == -1) {
level_first = l;
level_prev[l] = -1;
}
else {
level_next[level_last] = l;
level_prev[l] = level_last;
}
level_last = l;
level_next[l] = -1;
 
return sched_levels++;
/* allocate the descriptor! */
if (s < sizeof(level_des))
s = sizeof(level_des);
 
level_table[l] = (level_des *)kern_alloc(s);
 
*(level_table[l]) = level_default_descriptor;
 
level_size[l] = s;
 
/* return the descriptor index */
return l;
}
 
 
/*+ This function release a level descriptor previously allocated using
level_alloc_descriptor().
 
The function returns 0 if the level has been freed, or -1 if someone is
using it, -2 if the level has never been registered.
 
+*/
int level_free_descriptor(LEVEL l)
{
if (level_used[l] == 0)
return -2;
else if (level_used[l] > 1)
return -1;
 
/* we can free the descriptor */
level_used[l] = 0;
 
/* remove it from the "first" queue */
if (level_prev[l] == -1)
level_first = level_next[l];
else
level_next[level_prev[l]] = level_next[l];
if (level_next[l] == -1)
level_last = level_prev[l];
else
level_prev[level_next[l]] = level_prev[l];
/* ... and put it in the free queue */
level_prev[level_free] = l;
level_next[l] = level_free;
level_free = l;
 
/* finally, free the memory allocated to it */
kern_free(level_table[l], level_size[l]);
 
return 0;
}
 
/* Call this if you want to say that your module is using module l
(e.g., for calling its private functions) */
int level_use_descriptor(LEVEL l)
{
return ++level_used[l];
}
 
/* Call this when you no more need the module l */
int level_unuse_descriptor(LEVEL l)
{
return --level_used[l];
}
 
 
/*+ This function returns a resource_des **. the value returned shall be
used to register a resource module. The function shall be called only at
module registration time. It assume that the system is not yet
225,12 → 375,17
if (res_levels == MAX_RES_LEVEL)
{
printk("Too many resource levels!!!\n");
l1_exit(1);
sys_end();
}
 
return res_levels++;
}
 
 
/***********************************************************************
* Parameter parsing (argc, argv)
***********************************************************************/
 
/*+ This function compute the command line parameters from the multiboot_info
NOTE: this function modify the multiboot struct, so this function and
__call_main__ are mutually exclusives!!! +*/