* Reduced stack usage for iterator_get_next_module() quite a bit by no

longer pushing a whole path on the stack.
* open_module_list() now adds the prefix to the paths it puts on the
  stack to reduce the amount of searching to do (this probably wasn't
  done before because of the earlier boot method via bootfs which
  didn't allow for deep path names).
* module.c is now module.cpp (for KPath usage).


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16584 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2006-03-05 18:09:19 +00:00
parent f97a4547ac
commit 5d13c758d1
2 changed files with 33 additions and 25 deletions

View File

@ -22,7 +22,7 @@ KernelMergeObject kernel_core.o :
linkhack.c
lock.c
main.c
module.c
module.cpp
port.c
real_time_clock.c
scheduler.cpp

View File

@ -6,18 +6,18 @@
* Distributed under the terms of the NewOS License.
*/
/* The Module manager
* Manages kernel add-ons and their exported modules.
*/
/** Manages kernel add-ons and their exported modules. */
#include <boot_device.h>
#include <elf.h>
#include <kmodule.h>
#include <lock.h>
#include <util/khash.h>
#include <vfs.h>
#include <boot/elf.h>
#include <fs/KPath.h>
#include <util/khash.h>
#include <errno.h>
#include <stdlib.h>
@ -62,14 +62,14 @@ static module_info *sBuiltInModules[] = {
NULL
};
typedef enum {
enum module_state {
MODULE_QUERIED = 0,
MODULE_LOADED,
MODULE_INIT,
MODULE_READY,
MODULE_UNINIT,
MODULE_ERROR
} module_state;
};
/* Each loaded module image (which can export several modules) is put
@ -79,7 +79,7 @@ typedef enum {
* a little bit slower, but would lower the memory foot print quite a lot.
*/
typedef struct module_image {
struct module_image {
struct module_image *next;
module_info **info; /* the module_info we use */
module_dependency *dependencies;
@ -87,15 +87,15 @@ typedef struct module_image {
image_id image;
int32 ref_count; /* how many ref's to this file */
bool keep_loaded;
} module_image;
};
/* Each known module will have this structure which is put in the
* gModulesHash, and looked up by name.
*/
typedef struct module {
struct module {
struct module *next;
module_image *module_image;
::module_image *module_image;
char *name;
char *file;
int32 ref_count;
@ -103,7 +103,7 @@ typedef struct module {
int32 offset; /* this is the offset in the headers */
module_state state; /* state of module */
uint32 flags;
} module;
};
#define B_BUILT_IN_MODULE 2
@ -124,7 +124,7 @@ typedef struct module_iterator {
int32 module_offset;
/* This is used to keep track of which module_info
* within a module we're addressing. */
module_image *module_image;
::module_image *module_image;
module_info **current_header;
const char *current_path;
uint32 path_base_length;
@ -738,13 +738,10 @@ nextPath:
nextModuleImage:
if (iterator->current_header == NULL) {
// get next entry from the current directory
char path[B_PATH_NAME_LENGTH];
struct dirent *dirent;
struct stat st;
int32 passedOffset, commonLength;
errno = 0;
struct dirent *dirent;
if ((dirent = readdir(iterator->current_dir)) == NULL) {
closedir(iterator->current_dir);
iterator->current_dir = NULL;
@ -756,6 +753,7 @@ nextModuleImage:
}
// check if the prefix matches
int32 passedOffset, commonLength;
passedOffset = strlen(iterator->current_path) + 1;
commonLength = iterator->path_base_length + iterator->prefix_length - passedOffset;
@ -776,11 +774,17 @@ nextModuleImage:
goto nextModuleImage;
// build absolute path to current file
KPath pathBuffer;
if (pathBuffer.InitCheck() != B_OK)
return B_NO_MEMORY;
char *path = pathBuffer.LockBuffer();
strlcpy(path, iterator->current_path, sizeof(path));
strlcat(path, "/", sizeof(path));
strlcat(path, dirent->d_name, sizeof(path));
// find out if it's a directory or a file
struct stat st;
if (stat(path, &st) < 0)
return errno;
@ -1096,17 +1100,22 @@ open_module_list(const char *prefix)
// put all search paths on the stack
for (i = 0; i < NUM_MODULE_PATHS; i++) {
const char *path;
if (sDisableUserAddOns && i >= FIRST_USER_MODULE_PATH)
break;
path = strdup(sModulePaths[i]);
// Build path component: base path + '/' + prefix
size_t length = strlen(sModulePaths[i]);
char *path = (char *)malloc(length + iterator->prefix_length + 2);
if (path == NULL) {
// ToDo: should we abort the whole operation here?
// if we do, don't forget to empty the stack
continue;
}
memcpy(path, sModulePaths[i], length);
path[length] = '/';
memcpy(path + length + 1, prefix, iterator->prefix_length + 1);
iterator_push_path_on_stack(iterator, path, strlen(path) + 1);
}
@ -1192,10 +1201,6 @@ read_next_module_name(void *cookie, char *buffer, size_t *_bufferSize)
status_t
get_next_loaded_module_name(uint32 *_cookie, char *buffer, size_t *_bufferSize)
{
hash_iterator *iterator = (hash_iterator *)*_cookie;
struct module *module;
status_t status;
if (sModulesHash == NULL) {
dprintf("get_next_loaded_module_name() called too early!\n");
return NULL;
@ -1206,6 +1211,9 @@ get_next_loaded_module_name(uint32 *_cookie, char *buffer, size_t *_bufferSize)
if (_cookie == NULL || buffer == NULL || _bufferSize == NULL)
return B_BAD_VALUE;
hash_iterator *iterator = (hash_iterator *)*_cookie;
status_t status;
if (iterator == NULL) {
iterator = hash_open(sModulesHash, NULL);
if (iterator == NULL)
@ -1216,7 +1224,7 @@ get_next_loaded_module_name(uint32 *_cookie, char *buffer, size_t *_bufferSize)
recursive_lock_lock(&sModulesLock);
module = hash_next(sModulesHash, iterator);
struct module *module = (struct module *)hash_next(sModulesHash, iterator);
if (module != NULL) {
*_bufferSize = strlcpy(buffer, module->name, *_bufferSize);
status = B_OK;