diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2013-01-17 14:43:55 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2013-01-17 14:43:55 +0000 |
commit | e9d0885500d437cc6c89370d8131913bd1e7310b (patch) | |
tree | d9cf39f88361f174a2350d354ffb5584d43e2fc4 /nuttx/binfmt | |
parent | caeef71797019505fd450b1a0ae573ac5e490c6e (diff) | |
download | px4-firmware-e9d0885500d437cc6c89370d8131913bd1e7310b.tar.gz px4-firmware-e9d0885500d437cc6c89370d8131913bd1e7310b.tar.bz2 px4-firmware-e9d0885500d437cc6c89370d8131913bd1e7310b.zip |
Add logic to automatically unload module on exit; Several patches from Mike Smith
git-svn-id: http://svn.code.sf.net/p/nuttx/code/trunk@5528 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/binfmt')
-rw-r--r-- | nuttx/binfmt/Makefile | 4 | ||||
-rw-r--r-- | nuttx/binfmt/binfmt_exec.c | 69 | ||||
-rw-r--r-- | nuttx/binfmt/builtin.c | 8 | ||||
-rw-r--r-- | nuttx/binfmt/libbuiltin/libbuiltin_getname.c | 14 | ||||
-rw-r--r-- | nuttx/binfmt/libbuiltin/libbuiltin_isavail.c | 7 |
5 files changed, 89 insertions, 13 deletions
diff --git a/nuttx/binfmt/Makefile b/nuttx/binfmt/Makefile index 49dcd3d32..2f692beb1 100644 --- a/nuttx/binfmt/Makefile +++ b/nuttx/binfmt/Makefile @@ -52,6 +52,10 @@ ifeq ($(CONFIG_BINFMT_EXEPATH),y) BINFMT_CSRCS += binfmt_exepath.c endif +ifeq ($(CONFIG_SCHED_HAVE_PARENT),y) +BINFMT_CSRCS += binfmt_schedunload.c +endif + # Symbol table source files BINFMT_CSRCS += symtab_findbyname.c symtab_findbyvalue.c diff --git a/nuttx/binfmt/binfmt_exec.c b/nuttx/binfmt/binfmt_exec.c index d878c8cc5..1cead4384 100644 --- a/nuttx/binfmt/binfmt_exec.c +++ b/nuttx/binfmt/binfmt_exec.c @@ -74,7 +74,9 @@ * * Description: * This is a convenience function that wraps load_ and exec_module into - * one call. + * one call. If CONFIG_SCHED_ONEXIT is also defined, this function will + * automatically call schedule_unload() to unload the module when task + * exits. * * Input Parameter: * filename - Fulll path to the binary to be loaded @@ -84,7 +86,7 @@ * * Returned Value: * This is an end-user function, so it follows the normal convention: - * Returns the PID of the exec'ed module. On failure, it.returns + * It returns the PID of the exec'ed module. On failure, it returns * -1 (ERROR) and sets errno appropriately. * ****************************************************************************/ @@ -92,6 +94,66 @@ int exec(FAR const char *filename, FAR const char **argv, FAR const struct symtab_s *exports, int nexports) { +#ifdef CONFIG_SCHED_ONEXIT + FAR struct binary_s *bin; + int errorcode; + int ret; + + /* Allocate the load information */ + + bin = (FAR struct binary_s *)kzalloc(sizeof(struct binary_s)); + if (!bin) + { + set_errno(ENOMEM); + return ERROR; + } + + /* Load the module into memory */ + + bin->filename = filename; + bin->exports = exports; + bin->nexports = nexports; + + ret = load_module(bin); + if (ret < 0) + { + bdbg("ERROR: Failed to load program '%s'\n", filename); + kfree(bin); + return ERROR; + } + + /* Disable pre-emption so that the executed module does + * not return until we get a chance to connect the on_exit + * handler. + */ + + sched_lock(); + + /* Then start the module */ + + ret = exec_module(bin); + if (ret < 0) + { + bdbg("ERROR: Failed to execute program '%s'\n", filename); + sched_unlock(); + unload_module(bin); + kfree(bin); + return ERROR; + } + + /* Set up to unload the module (and free the binary_s structure) + * when the task exists. + */ + + ret = schedul_unload(ret, bin); + if (ret < 0) + { + bdbg("ERROR: Failed to schedul unload '%s'\n", filename); + } + + sched_unlock(); + return ret; +#else struct binary_s bin; int ret; @@ -119,7 +181,10 @@ int exec(FAR const char *filename, FAR const char **argv, return ERROR; } + /* TODO: How does the module get unloaded in this case? */ + return ret; +#endif } #endif /* CONFIG_BINFMT_DISABLE */ diff --git a/nuttx/binfmt/builtin.c b/nuttx/binfmt/builtin.c index d36cb6326..d80d9f5d8 100644 --- a/nuttx/binfmt/builtin.c +++ b/nuttx/binfmt/builtin.c @@ -89,6 +89,7 @@ static struct binfmt_s g_builtin_binfmt = static int builtin_loadbinary(struct binary_s *binp) { FAR const char *filename; + FAR const struct builtin_s *b; int fd; int index; int ret; @@ -134,9 +135,10 @@ static int builtin_loadbinary(struct binary_s *binp) * the priority. That is a bug and needs to be fixed. */ - binp->entrypt = g_builtins[index].main; - binp->stacksize = g_builtins[index].stacksize; - binp->priority = g_builtins[index].priority; + b = builtin_for_index(index); + binp->entrypt = b->main; + binp->stacksize = b->stacksize; + binp->priority = b->priority; return OK; } diff --git a/nuttx/binfmt/libbuiltin/libbuiltin_getname.c b/nuttx/binfmt/libbuiltin/libbuiltin_getname.c index 01ac024f7..9da2bac29 100644 --- a/nuttx/binfmt/libbuiltin/libbuiltin_getname.c +++ b/nuttx/binfmt/libbuiltin/libbuiltin_getname.c @@ -83,10 +83,14 @@ FAR const char *builtin_getname(int index) { - if (index < 0 || index >= number_builtins()) - { - return NULL; - } + struct builtin_s *b; - return g_builtins[index].name; + b = builtin_for_index(index); + + if (b != NULL) + { + return b->name; + } + + return NULL; } diff --git a/nuttx/binfmt/libbuiltin/libbuiltin_isavail.c b/nuttx/binfmt/libbuiltin/libbuiltin_isavail.c index f99a4b81d..b1d55ff21 100644 --- a/nuttx/binfmt/libbuiltin/libbuiltin_isavail.c +++ b/nuttx/binfmt/libbuiltin/libbuiltin_isavail.c @@ -80,18 +80,19 @@ * Name: builtin_isavail * * Description: - * Return the index into the table of applications for the applicaiton with + * Return the index into the table of applications for the application with * the name 'appname'. * ****************************************************************************/ int builtin_isavail(FAR const char *appname) { + FAR const char *n; int i; - for (i = 0; g_builtins[i].name; i++) + for (i = 0; n = builtin_getname(i); i++) { - if (!strncmp(g_builtins[i].name, appname, NAME_MAX)) + if (!strncmp(n, appname, NAME_MAX)) { return i; } |