summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2013-01-17 14:43:55 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2013-01-17 14:43:55 +0000
commitd8d9cc8a96cdc2219af7bec8142e7633779fd685 (patch)
treed9cf39f88361f174a2350d354ffb5584d43e2fc4
parent4f0e8b1249c1550bac83f9db61c67094bc6afc2d (diff)
downloadnuttx-d8d9cc8a96cdc2219af7bec8142e7633779fd685.tar.gz
nuttx-d8d9cc8a96cdc2219af7bec8142e7633779fd685.tar.bz2
nuttx-d8d9cc8a96cdc2219af7bec8142e7633779fd685.zip
Add logic to automatically unload module on exit; Several patches from Mike Smith
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5528 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r--apps/builtin/Makefile2
-rw-r--r--apps/builtin/builtin.c33
-rw-r--r--apps/builtin/exec_builtin.c16
-rw-r--r--nuttx/TODO23
-rw-r--r--nuttx/binfmt/Makefile4
-rw-r--r--nuttx/binfmt/binfmt_exec.c69
-rw-r--r--nuttx/binfmt/builtin.c8
-rw-r--r--nuttx/binfmt/libbuiltin/libbuiltin_getname.c14
-rw-r--r--nuttx/binfmt/libbuiltin/libbuiltin_isavail.c7
-rw-r--r--nuttx/configs/sim/nsh/defconfig3
-rw-r--r--nuttx/fs/binfs/fs_binfs.c10
-rw-r--r--nuttx/include/nuttx/binfmt/binfmt.h47
-rw-r--r--nuttx/include/nuttx/binfmt/builtin.h26
-rw-r--r--nuttx/sched/Kconfig36
-rw-r--r--nuttx/tools/Makefile.export12
15 files changed, 214 insertions, 96 deletions
diff --git a/apps/builtin/Makefile b/apps/builtin/Makefile
index d77054f41..f89532871 100644
--- a/apps/builtin/Makefile
+++ b/apps/builtin/Makefile
@@ -39,7 +39,7 @@ include $(APPDIR)/Make.defs
# Source and object files
ASRCS =
-CSRCS = builtin.c exec_builtin.c
+CSRCS = builtin.c builtin_list.c exec_builtin.c
AOBJS = $(ASRCS:.S=$(OBJEXT))
COBJS = $(CSRCS:.c=$(OBJEXT))
diff --git a/apps/builtin/builtin.c b/apps/builtin/builtin.c
index 7655a531d..d26f0a044 100644
--- a/apps/builtin/builtin.c
+++ b/apps/builtin/builtin.c
@@ -55,27 +55,8 @@
* Public Data
****************************************************************************/
-#undef EXTERN
-#if defined(__cplusplus)
-#define EXTERN extern "C"
-extern "C" {
-#else
-#define EXTERN extern
-#endif
-
-#include "builtin_proto.h"
-
-const struct builtin_s g_builtins[] =
-{
-# include "builtin_list.h"
- { NULL, 0, 0, 0 }
-};
-
-#undef EXTERN
-#if defined(__cplusplus)
-}
-#endif
-
+extern const struct builtin_s g_builtins[];
+extern const int g_builtin_count;
/****************************************************************************
* Private Data
@@ -89,9 +70,11 @@ const struct builtin_s g_builtins[] =
* Public Functions
****************************************************************************/
-int number_builtins(void)
+FAR const struct builtin_s *builtin_for_index(int index)
{
- return sizeof(g_builtins)/sizeof(struct builtin_s) - 1;
+ if (index < g_builtin_count)
+ {
+ return &g_builtins[index];
+ }
+ return NULL;
}
-
-
diff --git a/apps/builtin/exec_builtin.c b/apps/builtin/exec_builtin.c
index 05648590d..d4431164c 100644
--- a/apps/builtin/exec_builtin.c
+++ b/apps/builtin/exec_builtin.c
@@ -142,8 +142,17 @@ static void bultin_semtake(FAR sem_t *sem)
static int builtin_taskcreate(int index, FAR const char **argv)
{
+ FAR const struct builtin_s *b;
int ret;
+ b = builtin_for_index(index);
+
+ if (b == NULL)
+ {
+ errno = ENOENT;
+ return ERROR;
+ }
+
/* Disable pre-emption. This means that although we start the builtin
* application here, it will not actually run until pre-emption is
* re-enabled below.
@@ -153,8 +162,7 @@ static int builtin_taskcreate(int index, FAR const char **argv)
/* Start the builtin application task */
- ret = TASK_CREATE(g_builtins[index].name, g_builtins[index].priority,
- g_builtins[index].stacksize, g_builtins[index].main,
+ ret = TASK_CREATE(b->name, b->priority, b->stacksize, b->main,
(argv) ? &argv[1] : (FAR const char **)NULL);
/* If robin robin scheduling is enabled, then set the scheduling policy
@@ -171,7 +179,7 @@ static int builtin_taskcreate(int index, FAR const char **argv)
* new task cannot yet have changed from its initial value.
*/
- param.sched_priority = g_builtins[index].priority;
+ param.sched_priority = b->priority;
(void)sched_setscheduler(ret, SCHED_RR, &param);
}
#endif
@@ -293,8 +301,6 @@ static inline int builtin_startproxy(int index, FAR const char **argv,
int errcode;
int ret;
- DEBUGASSERT(path);
-
svdbg("index=%d argv=%p redirfile=%s oflags=%04x\n",
index, argv, redirfile, oflags);
diff --git a/nuttx/TODO b/nuttx/TODO
index 248d2dafa..91b4aebaa 100644
--- a/nuttx/TODO
+++ b/nuttx/TODO
@@ -6,7 +6,7 @@ standards, things that could be improved, and ideas for enhancements.
nuttx/
- (10) Task/Scheduler (sched/)
+ (11) Task/Scheduler (sched/)
(1) Memory Managment (mm/)
(3) Signals (sched/, arch/)
(2) pthreads (sched/)
@@ -193,7 +193,7 @@ o Task/Scheduler (sched/)
Priority: Low
Title: IMPROVED TASK CONTROL BLOCK STRUCTURE
- All task resources that are shared amongst threads have
+ Description: All task resources that are shared amongst threads have
their own "break-away", reference-counted structure. The
Task Control Block (TCB) of each thread holds a reference
to each breakaway structure (see include/nuttx/sched.h).
@@ -206,11 +206,26 @@ o Task/Scheduler (sched/)
- File descriptors (struct filelist)
- FILE streams (struct streamlist)
- Sockets (struct socketlist)
- Status: Open
- Priority: Low. This is an enhancement. It would slight reduce
+ Status: Open
+ Priority: Low. This is an enhancement. It would slight reduce
memory usage but would also increase coupling. These
resources are nicely modular now.
+ Title: ISSUES WITH atexit() AND on_exit()
+ Description: These functions execute with the following bad properties:
+
+ 1. They run with interrupts disabled,
+ 2. They run in supervisor mode (if applicable), and
+ 3. They do not obey any setup of PIC or address
+ environments. Do they need to?
+
+ The fix for all of these issues it to have the callbacks
+ run on the caller's thread (as with signal handlers).
+ Status: Open
+ Priority: Medium Low. This is an important change to some less
+ important interfaces. For the average user, these
+ functions are just fine the way they are.
+
o Memory Managment (mm/)
^^^^^^^^^^^^^^^^^^^^^^
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;
}
diff --git a/nuttx/configs/sim/nsh/defconfig b/nuttx/configs/sim/nsh/defconfig
index 8dc5ddcce..c5eadb122 100644
--- a/nuttx/configs/sim/nsh/defconfig
+++ b/nuttx/configs/sim/nsh/defconfig
@@ -116,7 +116,7 @@ CONFIG_MSEC_PER_TICK=10
CONFIG_RR_INTERVAL=0
# CONFIG_SCHED_INSTRUMENTATION is not set
CONFIG_TASK_NAME_SIZE=32
-# CONFIG_SCHED_HAVE_PARENT is not set
+CONFIG_SCHED_HAVE_PARENT=y
# CONFIG_JULIAN_TIME is not set
CONFIG_START_YEAR=2008
CONFIG_START_MONTH=6
@@ -148,6 +148,7 @@ CONFIG_DISABLE_POLL=y
CONFIG_SIG_SIGUSR1=1
CONFIG_SIG_SIGUSR2=2
CONFIG_SIG_SIGALARM=3
+CONFIG_SIG_SIGCHLD=4
CONFIG_SIG_SIGCONDTIMEDOUT=16
#
diff --git a/nuttx/fs/binfs/fs_binfs.c b/nuttx/fs/binfs/fs_binfs.c
index ed6326eba..56ea472af 100644
--- a/nuttx/fs/binfs/fs_binfs.c
+++ b/nuttx/fs/binfs/fs_binfs.c
@@ -222,7 +222,7 @@ static int binfs_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
}
else
{
- *ptr = g_builtins[(int)filep->f_priv].name;
+ *ptr = builtin_getname((int)filep->f_priv);
ret = OK;
}
}
@@ -287,13 +287,15 @@ static int binfs_opendir(struct inode *mountpt, const char *relpath,
static int binfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir)
{
+ FAR const char *name;
unsigned int index;
int ret;
/* Have we reached the end of the directory */
index = dir->u.binfs.fb_index;
- if (g_builtins[index].name == NULL)
+ name = builtin_getname(index);
+ if (name == NULL)
{
/* We signal the end of the directory by returning the
* special error -ENOENT
@@ -306,9 +308,9 @@ static int binfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir)
{
/* Save the filename and file type */
- fvdbg("Entry %d: \"%s\"\n", index, g_builtins[index].name);
+ fvdbg("Entry %d: \"%s\"\n", index, name);
dir->fd_dir.d_type = DTYPE_FILE;
- strncpy(dir->fd_dir.d_name, g_builtins[index].name, NAME_MAX+1);
+ strncpy(dir->fd_dir.d_name, name, NAME_MAX+1);
/* The application list is terminated by an entry with a NULL name.
* Therefore, there is at least one more entry in the list.
diff --git a/nuttx/include/nuttx/binfmt/binfmt.h b/nuttx/include/nuttx/binfmt/binfmt.h
index c6c7c874a..472ba0fc4 100644
--- a/nuttx/include/nuttx/binfmt/binfmt.h
+++ b/nuttx/include/nuttx/binfmt/binfmt.h
@@ -82,6 +82,18 @@ typedef FAR void (*binfmt_dtor_t)(void);
struct symtab_s;
struct binary_s
{
+ /* If CONFIG_SCHED_HAVE_PARENT is defined then schedul_unload() will
+ * manage instances of struct binary_s allocated with kmalloc. It
+ * will keep the binary data in a link list and when SIGCHLD is received
+ * (meaning that the task has exit'ed, schedul_unload() will find the
+ * data, unload the module, and free the structure.
+ */
+
+#ifdef CONFIG_SCHED_HAVE_PARENT
+ FAR struct binary_s *flink; /* Supports a singly linked list */
+ pid_t pid; /* Task ID of the child task */
+#endif
+
/* Information provided to the loader to load and bind a module */
FAR const char *filename; /* Full path to the binary to be loaded (See NOTE 1 above) */
@@ -222,7 +234,7 @@ int unload_module(FAR const struct binary_s *bin);
*
* 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
+ * Returns the PID of the exec'ed module. On failure, it returns
* -1 (ERROR) and sets errno appropriately.
*
****************************************************************************/
@@ -230,11 +242,40 @@ int unload_module(FAR const struct binary_s *bin);
int exec_module(FAR const struct binary_s *bin);
/****************************************************************************
+ * Name: schedule_unload
+ *
+ * Description:
+ * If CONFIG_SCHED_HAVE_PARENT is defined, this function may be called by
+ * the parent of the the newly created task to automatically unload the
+ * module when the task exits. This assumes that (1) the caller is the
+ * parent of the created task, (2) that bin was allocated with kmalloc()
+ * or friends. It will also automatically free the structure with kfree()
+ * after unloading the module.
+ *
+ * Input Parameter:
+ * pid - The task ID of the child task
+ * bin - This structure must have been allocated with kmalloc() and must
+ * persist until the task unloads
+ *
+ * Returned Value:
+ * This is an end-user function, so it follows the normal convention:
+ * It returns 0 (OK) if the callback was successfully scheduled. On
+ * failure, it returns -1 (ERROR) and sets errno appropriately.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_SCHED_HAVE_PARENT
+int schedule_unload(pid_t pid, FAR const struct binary_s *bin);
+#endif
+
+/****************************************************************************
* Name: exec
*
* 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
@@ -244,7 +285,7 @@ int exec_module(FAR const struct binary_s *bin);
*
* 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.
*
****************************************************************************/
diff --git a/nuttx/include/nuttx/binfmt/builtin.h b/nuttx/include/nuttx/binfmt/builtin.h
index 632f8944d..5921cc518 100644
--- a/nuttx/include/nuttx/binfmt/builtin.h
+++ b/nuttx/include/nuttx/binfmt/builtin.h
@@ -73,14 +73,6 @@ extern "C" {
#define EXTERN extern
#endif
-/* The g_builtins[] array holds information about each builtin function. If
- * support for builtin functions is enabled in the NuttX configuration, then
- * this arrary (along with the number_builtins() function) must be provided
- * by the application code.
- */
-
-EXTERN const struct builtin_s g_builtins[];
-
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -128,24 +120,24 @@ FAR const char *builtin_getname(int index);
* Data Set Access Functions Provided to Applications by binfmt/libbuiltin
****************************************************************************/
/****************************************************************************
- * Name: number_builtins
+ * Name: builtin_for_index
*
* Description:
- * Returns the number of builtin functions in the g_builtins[] array. If
- * support for builtin functions is enabled in the NuttX configuration,
- * then this function (along with g_builtins[]) must be provided by the
- * application code.
+ * Returns the builtin_s structure for the selected builtin.
+ * If support for builtin functions is enabled in the NuttX configuration,
+ * then this function must be provided by the application code.
*
* Input Parameter:
- * None
+ * index, from 0 and on...
*
* Returned Value:
- * The number of entries in the g_builtins[] array. This function does
- * not return failures.
+ * Returns valid pointer pointing to the builtin_s structure if index is
+ * valid.
+ * Otherwise, NULL is returned.
*
****************************************************************************/
-int number_builtins(void);
+EXTERN FAR const struct builtin_s *builtin_for_index(int index);
#undef EXTERN
#if defined(__cplusplus)
diff --git a/nuttx/sched/Kconfig b/nuttx/sched/Kconfig
index 6d53a03aa..11d74b583 100644
--- a/nuttx/sched/Kconfig
+++ b/nuttx/sched/Kconfig
@@ -4,7 +4,7 @@
#
config MSEC_PER_TICK
- int "tick timer"
+ int "Milliseconds per system timer tick"
default 10
---help---
The default system timer is 100Hz or MSEC_PER_TICK=10. This setting
@@ -12,7 +12,7 @@ config MSEC_PER_TICK
system timer interrupts at some interrupt interval other than 10 msec.
config RR_INTERVAL
- int "round robin timeslice"
+ int "Round robin timeslice (MSEC)"
default 0
---help---
The round robin timeslice will be set this number of milliseconds;
@@ -39,7 +39,7 @@ config TASK_NAME_SIZE
disable.
config SCHED_HAVE_PARENT
- bool "Remember Parent"
+ bool "Support parent/child task relationships"
default n
---help---
Remember the ID of the parent thread when a new child thread is
@@ -56,15 +56,15 @@ config JULIAN_TIME
Enables Julian time conversions
config START_YEAR
- int "start year"
+ int "Start year"
default 2013
config START_MONTH
- int "start month"
+ int "Start month"
default 1
config START_DAY
- int "start day"
+ int "Start day"
default 1
config DEV_CONSOLE
@@ -372,7 +372,7 @@ endif
comment "Sizes of configurable things (0 disables)"
config MAX_TASKS
- int "Max tasks"
+ int "Max number of tasks"
default 32
---help---
The maximum number of simultaneously active tasks. This value must be
@@ -386,33 +386,32 @@ config MAX_TASK_ARGS
receive (i.e., maxmum value of 'argc')
config NPTHREAD_KEYS
- int "Number of pthread keys"
+ int "Maximum number of pthread keys"
default 4
---help---
The number of items of thread-
specific data that can be retained
config NFILE_DESCRIPTORS
- int "Max file descriptors"
+ int "Maximum number of file descriptors per task"
default 16
---help---
- The maximum number of file
- descriptors (one for each open)
+ The maximum number of file descriptors per task (one for each open)
config NFILE_STREAMS
- int "Max file streams"
+ int "Maximum number of FILE streams"
default 16
---help---
The maximum number of streams that can be fopen'ed
config NAME_MAX
- int "name max"
+ int "Maximum size of a file name"
default 32
---help---
The maximum size of a file name.
config PREALLOC_MQ_MSGS
- int "Pre-allocated messages"
+ int "Number of pre-allocated messages"
default 32
---help---
The number of pre-allocated message structures. The system manages
@@ -426,21 +425,20 @@ config MQ_MAXMSGSIZE
setting (does not include other message structure overhead.
config MAX_WDOGPARMS
- int "max watchdog parms"
+ int "Maximum number of watchdog parameters"
default 4
---help---
- Maximum number of parameters that
- can be passed to a watchdog handler
+ Maximum number of parameters that can be passed to a watchdog handler
config PREALLOC_WDOGS
- int "Pre-allocated watchdogs"
+ int "Number of pre-allocated watchdog timers"
default 32
---help---
The number of pre-allocated watchdog structures. The system manages a
pool of preallocated watchdog structures to minimize dynamic allocations
config PREALLOC_TIMERS
- int "Pre-allocated timers"
+ int "Number of pre-allocated POSIX timers"
default 8
---help---
The number of pre-allocated POSIX timer structures. The system manages a
diff --git a/nuttx/tools/Makefile.export b/nuttx/tools/Makefile.export
index 002cb526b..6dfe72bf9 100644
--- a/nuttx/tools/Makefile.export
+++ b/nuttx/tools/Makefile.export
@@ -37,14 +37,18 @@ include $(TOPDIR)/.config
include $(EXPORTDIR)/Make.defs
ifdef ARCHSCRIPT
+#
+# ARCHSCRIPT may contain a leading -T; it must not be followed by a space
+# for this to work.
+#
ifeq ($(WINTOOL),y)
-LDPATH = ${shell cygpath -u $(patsubst -T,,$(ARCHSCRIPT))}
+LDPATH = $(shell cygpath -u $(patsubst -T%,%,$(ARCHSCRIPT)))
else
-LDPATH = $(patsubst -T,,$(ARCHSCRIPT))
+LDPATH = $(patsubst -T%,%,$(ARCHSCRIPT))
endif
-LDNAME = ${shell basename ${LDPATH}}
-LDDIR = ${shell dirname ${LDPATH}}
+LDNAME = ${notdir ${LDPATH}}
+LDDIR = ${dir ${LDPATH}}
endif
ARCHSUBDIR = "arch/$(CONFIG_ARCH)/src"