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!!! +*/ |