Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/kern_linker.c
Show First 20 Lines • Show All 189 Lines • ▼ Show 20 Lines | linker_add_class(linker_class_t lc) | ||||
((kobj_class_t)lc)->refs++; /* XXX: kobj_mtx */ | ((kobj_class_t)lc)->refs++; /* XXX: kobj_mtx */ | ||||
TAILQ_INSERT_TAIL(&classes, lc, link); | TAILQ_INSERT_TAIL(&classes, lc, link); | ||||
return (0); | return (0); | ||||
} | } | ||||
static void | static void | ||||
linker_file_sysinit(linker_file_t lf) | linker_file_sysinit(linker_file_t lf) | ||||
{ | { | ||||
struct sysinit **start, **stop, **sipp, **xipp, *save; | struct sysinit **start, **stop, **sipp; | ||||
int last; | uint32_t last; | ||||
KLD_DPF(FILE, ("linker_file_sysinit: calling SYSINITs for %s\n", | KLD_DPF(FILE, ("linker_file_sysinit: calling SYSINITs for %s\n", | ||||
lf->filename)); | lf->filename)); | ||||
sx_assert(&kld_sx, SA_XLOCKED); | sx_assert(&kld_sx, SA_XLOCKED); | ||||
if (linker_file_lookup_set(lf, "sysinit_set", &start, &stop, NULL) != 0) | if (linker_file_lookup_set(lf, "sysinit_set", &start, &stop, NULL) != 0) | ||||
return; | return; | ||||
/* | |||||
* Perform a bubble sort of the system initialization objects by | |||||
* their subsystem (primary key) and order (secondary key). | |||||
* | |||||
* Since some things care about execution order, this is the operation | |||||
* which ensures continued function. | |||||
*/ | |||||
for (sipp = start; sipp < stop; sipp++) { | |||||
for (xipp = sipp + 1; xipp < stop; xipp++) { | |||||
if ((*sipp)->subsystem < (*xipp)->subsystem || | |||||
((*sipp)->subsystem == (*xipp)->subsystem && | |||||
(*sipp)->order <= (*xipp)->order)) | |||||
continue; /* skip */ | |||||
save = *sipp; | |||||
*sipp = *xipp; | |||||
*xipp = save; | |||||
} | |||||
} | |||||
sysinit_sort(start, stop); | |||||
/* | /* | ||||
* Traverse the (now) ordered list of system initialization tasks. | * Traverse the (now) ordered list of system initialization tasks. | ||||
* Perform each task, and continue on to the next task. | * Perform each task, and continue on to the next task. | ||||
*/ | */ | ||||
last = SI_SUB_DUMMY; | last = SI_SUB_DUMMY; | ||||
sx_xunlock(&kld_sx); | sx_xunlock(&kld_sx); | ||||
mtx_lock(&Giant); | mtx_lock(&Giant); | ||||
for (sipp = start; sipp < stop; sipp++) { | for (sipp = start; sipp < stop; sipp++) { | ||||
Show All 10 Lines | linker_file_sysinit(linker_file_t lf) | ||||
} | } | ||||
mtx_unlock(&Giant); | mtx_unlock(&Giant); | ||||
sx_xlock(&kld_sx); | sx_xlock(&kld_sx); | ||||
} | } | ||||
static void | static void | ||||
linker_file_sysuninit(linker_file_t lf) | linker_file_sysuninit(linker_file_t lf) | ||||
{ | { | ||||
struct sysinit **start, **stop, **sipp, **xipp, *save; | struct sysinit **start, **stop, **sipp; | ||||
int last; | uint32_t last; | ||||
KLD_DPF(FILE, ("linker_file_sysuninit: calling SYSUNINITs for %s\n", | KLD_DPF(FILE, ("linker_file_sysuninit: calling SYSUNINITs for %s\n", | ||||
lf->filename)); | lf->filename)); | ||||
sx_assert(&kld_sx, SA_XLOCKED); | sx_assert(&kld_sx, SA_XLOCKED); | ||||
if (linker_file_lookup_set(lf, "sysuninit_set", &start, &stop, | if (linker_file_lookup_set(lf, "sysuninit_set", &start, &stop, | ||||
NULL) != 0) | NULL) != 0) | ||||
return; | return; | ||||
/* | sysinit_sort(start, stop); | ||||
* Perform a reverse bubble sort of the system initialization objects | |||||
* by their subsystem (primary key) and order (secondary key). | |||||
* | |||||
* Since some things care about execution order, this is the operation | |||||
* which ensures continued function. | |||||
*/ | |||||
for (sipp = start; sipp < stop; sipp++) { | |||||
for (xipp = sipp + 1; xipp < stop; xipp++) { | |||||
if ((*sipp)->subsystem > (*xipp)->subsystem || | |||||
((*sipp)->subsystem == (*xipp)->subsystem && | |||||
(*sipp)->order >= (*xipp)->order)) | |||||
continue; /* skip */ | |||||
save = *sipp; | |||||
*sipp = *xipp; | |||||
*xipp = save; | |||||
} | |||||
} | |||||
/* | /* | ||||
* Traverse the (now) ordered list of system initialization tasks. | * Traverse the (now) ordered list of system initialization tasks. | ||||
* Perform each task, and continue on to the next task. | * Perform each task, and continue on to the next task. | ||||
*/ | */ | ||||
sx_xunlock(&kld_sx); | sx_xunlock(&kld_sx); | ||||
mtx_lock(&Giant); | mtx_lock(&Giant); | ||||
last = SI_SUB_DUMMY; | last = SI_SUB_DUMMY; | ||||
for (sipp = start; sipp < stop; sipp++) { | for (sipp = start; sipp < stop; sipp++) { | ||||
if ((*sipp)->subsystem == SI_SUB_DUMMY) | if ((*sipp)->subsystem == (SI_SUB_DUMMY ^ SI_SUB_LAST)) | ||||
continue; /* skip dummy task(s) */ | continue; /* skip dummy task(s) */ | ||||
if ((*sipp)->subsystem > last) | if ((*sipp)->subsystem > last) | ||||
BOOTTRACE("%s: sysuninit 0x%7x", lf->filename, | BOOTTRACE("%s: sysuninit 0x%7x", lf->filename, | ||||
(*sipp)->subsystem); | (*sipp)->subsystem ^ SI_SUB_LAST); | ||||
/* Call function */ | /* Call function */ | ||||
(*((*sipp)->func)) ((*sipp)->udata); | (*((*sipp)->func)) ((*sipp)->udata); | ||||
last = (*sipp)->subsystem; | last = (*sipp)->subsystem; | ||||
} | } | ||||
mtx_unlock(&Giant); | mtx_unlock(&Giant); | ||||
sx_xlock(&kld_sx); | sx_xlock(&kld_sx); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 2,047 Lines • Show Last 20 Lines |