diff --git a/ChangeLog b/ChangeLog index 255d69a3dbd1d4106cdae702f291ef2b37c2d0d4..32112f35865070000cc497fffb14f6734e6a0fc8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4040,3 +4040,9 @@ Move stream data from the TCB to the task group structure. * net/, sched/, and include/nuttx/net/net.h: Move socket data from the TCB to the task group structure. + * sched/task_starthook.c, sched/task_start.c, and include/nuttx/sched.h: + Add a task start hook that will be called before the task main + is started. This can be used to schedule C++ constructors to run + automatically in the context of the new task. + * binfmt/binfmt_execmodule: Execute constructors as a start hook. + diff --git a/TODO b/TODO index cb99f1bf71736ff3c71a229fe52d9bc69159efdb..05e0fa99b862135a7fd87cba2f7d66215972fa5e 100644 --- a/TODO +++ b/TODO @@ -1,4 +1,4 @@ -NuttX TODO List (Last updated January 26, 2013) +NuttX TODO List (Last updated January 27, 2013) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This file summarizes known NuttX bugs, limitations, inconsistencies with @@ -6,7 +6,7 @@ standards, things that could be improved, and ideas for enhancements. nuttx/ - (10) Task/Scheduler (sched/) + (11) Task/Scheduler (sched/) (2) Memory Managment (mm/) (3) Signals (sched/, arch/) (2) pthreads (sched/) @@ -193,6 +193,16 @@ o Task/Scheduler (sched/) Status: Open Priority: Low (it might as well be low since it isn't going to be fixed). + Title: errno IS NOT SHARED AMONG THREADS + Description: In NuttX, the errno value is unique for each thread. But for + bug-for-bug compatibility, the same errno should be shared by + the task and each thread that it creates. It is *very* easy + to make this change: Just move the pterrno field from + _TCB to struct task_group_s. However, I am still not sure + if this should be done or not. + Status: Open + Priority: Low + o Memory Managment (mm/) ^^^^^^^^^^^^^^^^^^^^^^ @@ -407,6 +417,9 @@ o Binary loaders (binfmt/) Description: Not all of the NXFLAT test under apps/examples/nxflat are working. Most simply do not compile yet. tests/mutex runs okay but outputs garbage on completion. + + Update: 13-27-1, tests/mutex crashed with a memory corruption + problem the last time that I ran it. Status: Open Priority: High diff --git a/binfmt/Kconfig b/binfmt/Kconfig index 8d6c0bb18fdecec0c1f17743e8ca870541057aa0..6e5f7c25134dad0f71433bfbb3b07132de58d3f2 100644 --- a/binfmt/Kconfig +++ b/binfmt/Kconfig @@ -72,9 +72,10 @@ config PIC config BINFMT_CONSTRUCTORS bool "C++ Static Constructor Support" default n - depends on HAVE_CXX && ELF # FIX ME: Currently only supported for ELF + depends on HAVE_CXX && SCHED_STARTHOOK && ELF ---help--- - Build in support for C++ constructors in loaded modules. + Build in support for C++ constructors in loaded modules. Currently + only support for ELF binary formats. config SYMTAB_ORDEREDBYNAME bool "Symbol Tables Ordered by Name" diff --git a/binfmt/binfmt_execmodule.c b/binfmt/binfmt_execmodule.c index afa445abb99d59bfd259955229a896a283d793ed..10068b482183476ddd710033cdef32d315d022a3 100644 --- a/binfmt/binfmt_execmodule.c +++ b/binfmt/binfmt_execmodule.c @@ -58,6 +58,14 @@ /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ +/* If C++ constructors are used, then CONFIG_SCHED_STARTHOOK must also be + * selected be the start hook is used to schedule execution of the + * constructors. + */ + +#if defined(CONFIG_BINFMT_CONSTRUCTORS) && !defined(CONFIG_SCHED_STARTHOOK) +# errror "CONFIG_SCHED_STARTHOOK must be defined to use constructors" +#endif /**************************************************************************** * Private Function Prototypes @@ -75,7 +83,9 @@ * Name: exec_ctors * * Description: - * Execute C++ static constructors. + * Execute C++ static constructors. This function is registered as a + * start hook and runs on the thread of the newly created task before + * the new task's main function is called. * * Input Parameters: * loadinfo - Load state information @@ -87,26 +97,12 @@ ****************************************************************************/ #ifdef CONFIG_BINFMT_CONSTRUCTORS -static inline int exec_ctors(FAR const struct binary_s *binp) +static void exec_ctors(FAR void *arg) { + FAR const struct binary_s *binp = (FAR const struct binary_s *)arg; binfmt_ctor_t *ctor = binp->ctors; -#ifdef CONFIG_ADDRENV - hw_addrenv_t oldenv; - int ret; -#endif int i; - /* Instantiate the address enviroment containing the constructors */ - -#ifdef CONFIG_ADDRENV - ret = up_addrenv_select(binp->addrenv, &oldenv); - if (ret < 0) - { - bdbg("up_addrenv_select() failed: %d\n", ret); - return ret; - } -#endif - /* Execute each constructor */ for (i = 0; i < binp->nctors; i++) @@ -116,14 +112,6 @@ static inline int exec_ctors(FAR const struct binary_s *binp) (*ctor)(); ctor++; } - - /* Restore the address enviroment */ - -#ifdef CONFIG_ADDRENV - return up_addrenv_restore(oldenv); -#else - return OK; -#endif } #endif @@ -139,7 +127,7 @@ static inline int exec_ctors(FAR const struct binary_s *binp) * * 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. * ****************************************************************************/ @@ -229,22 +217,19 @@ int exec_module(FAR const struct binary_s *binp) } #endif - /* Get the assigned pid before we start the task */ - - pid = tcb->pid; - - /* Execute all of the C++ static constructors */ + /* Setup a start hook that will execute all of the C++ static constructors + * on the newly created thread. The struct binary_s must persist at least + * until the new task has been started. + */ #ifdef CONFIG_BINFMT_CONSTRUCTORS - ret = exec_ctors(binp); - if (ret < 0) - { - err = -ret; - bdbg("exec_ctors() failed: %d\n", ret); - goto errout_with_stack; - } + task_starthook(tcb, exec_ctors, (FAR void *)binp); #endif + /* Get the assigned pid before we start the task */ + + pid = tcb->pid; + /* Then activate the task at the provided priority */ ret = task_activate(tcb); diff --git a/binfmt/binfmt_internal.h b/binfmt/binfmt_internal.h index 4fab9724d49dc5473db06ee867ec9d1b090c7994..fa750543a3e6b13db66d4621cd77fefe0ace18ca 100644 --- a/binfmt/binfmt_internal.h +++ b/binfmt/binfmt_internal.h @@ -71,7 +71,7 @@ EXTERN FAR struct binfmt_s *g_binfmts; * Public Function Prototypes ***********************************************************************/ -/* Dump the contents of strtuc binary_s */ +/* Dump the contents of struct binary_s */ #if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_BINFMT) EXTERN int dump_module(FAR const struct binary_s *bin); diff --git a/configs/stm32f4discovery/elf/defconfig b/configs/stm32f4discovery/elf/defconfig index 3f5a5d0fcf726d4049bb4c0845b20dda1c230772..f7e0dc5f2f5351e30348dd51de76dcc5888227df 100644 --- a/configs/stm32f4discovery/elf/defconfig +++ b/configs/stm32f4discovery/elf/defconfig @@ -69,7 +69,7 @@ CONFIG_ARCH="arm" # CONFIG_ARCH_CHIP_DM320 is not set # CONFIG_ARCH_CHIP_IMX is not set # CONFIG_ARCH_CHIP_KINETIS is not set -# CONFIG_ARCH_CHIP_LM3S is not set +# CONFIG_ARCH_CHIP_LM is not set # CONFIG_ARCH_CHIP_LPC17XX is not set # CONFIG_ARCH_CHIP_LPC214X is not set # CONFIG_ARCH_CHIP_LPC2378 is not set @@ -81,6 +81,7 @@ CONFIG_ARCH_CHIP_STM32=y CONFIG_ARCH_CORTEXM4=y CONFIG_ARCH_FAMILY="armv7-m" CONFIG_ARCH_CHIP="stm32" +CONFIG_ARMV7M_USEBASEPRI=y CONFIG_ARCH_HAVE_CMNVECTOR=y # CONFIG_ARMV7M_CMNVECTOR is not set # CONFIG_ARCH_FPU is not set @@ -201,26 +202,35 @@ CONFIG_STM32_JTAG_SW_ENABLE=y # CONFIG_STM32_FORCEPOWER is not set # CONFIG_ARCH_BOARD_STM32_CUSTOM_CLOCKCONFIG is not set CONFIG_STM32_CCMEXCLUDE=y +CONFIG_STM32_USART=y # # U[S]ART Configuration # # CONFIG_USART2_RS485 is not set +# CONFIG_STM32_USART_SINGLEWIRE is not set # # USB Host Configuration # +# +# External Memory Configuration +# + # # Architecture Options # # CONFIG_ARCH_NOINTC is not set +# CONFIG_ARCH_VECNOTIRQ is not set # CONFIG_ARCH_DMA is not set CONFIG_ARCH_IRQPRIO=y # CONFIG_CUSTOM_STACK is not set # CONFIG_ADDRENV is not set +CONFIG_ARCH_HAVE_VFORK=y CONFIG_ARCH_STACKDUMP=y # CONFIG_ENDIAN_BIG is not set +# CONFIG_ARCH_HAVE_RAMFUNCS is not set # # Board Settings @@ -266,6 +276,7 @@ CONFIG_MSEC_PER_TICK=10 CONFIG_RR_INTERVAL=200 # CONFIG_SCHED_INSTRUMENTATION is not set CONFIG_TASK_NAME_SIZE=0 +# CONFIG_SCHED_HAVE_PARENT is not set # CONFIG_JULIAN_TIME is not set CONFIG_START_YEAR=2012 CONFIG_START_MONTH=10 @@ -278,6 +289,7 @@ CONFIG_DEV_CONSOLE=y CONFIG_SDCLONE_DISABLE=y # CONFIG_SCHED_WORKQUEUE is not set # CONFIG_SCHED_WAITPID is not set +CONFIG_SCHED_STARTHOOK=y # CONFIG_SCHED_ATEXIT is not set # CONFIG_SCHED_ONEXIT is not set CONFIG_USER_ENTRYPOINT="elf_main" @@ -287,9 +299,15 @@ CONFIG_DISABLE_OS_API=y # CONFIG_DISABLE_PTHREAD is not set # CONFIG_DISABLE_SIGNALS is not set # CONFIG_DISABLE_MQUEUE is not set -# CONFIG_DISABLE_MOUNTPOINT is not set # CONFIG_DISABLE_ENVIRON is not set -# CONFIG_DISABLE_POLL is not set + +# +# Signal Numbers +# +CONFIG_SIG_SIGUSR1=1 +CONFIG_SIG_SIGUSR2=2 +CONFIG_SIG_SIGALARM=3 +CONFIG_SIG_SIGCONDTIMEDOUT=16 # # Sizes of configurable things (0 disables) @@ -317,6 +335,7 @@ CONFIG_PTHREAD_STACK_DEFAULT=2048 # # Device Drivers # +# CONFIG_DISABLE_POLL is not set CONFIG_DEV_NULL=y # CONFIG_DEV_ZERO is not set # CONFIG_LOOP is not set @@ -381,8 +400,9 @@ CONFIG_USART2_2STOP=0 # # File system configuration # -# CONFIG_FS_FAT is not set +# CONFIG_DISABLE_MOUNTPOINT is not set # CONFIG_FS_RAMMAP is not set +# CONFIG_FS_FAT is not set # CONFIG_FS_NXFFS is not set CONFIG_FS_ROMFS=y @@ -415,6 +435,7 @@ CONFIG_ELF_ALIGN_LOG2=2 CONFIG_ELF_STACKSIZE=2048 CONFIG_ELF_BUFFERSIZE=128 CONFIG_ELF_BUFFERINCR=32 +# CONFIG_BUILTIN is not set # CONFIG_PIC is not set CONFIG_BINFMT_CONSTRUCTORS=y CONFIG_SYMTAB_ORDEREDBYNAME=y @@ -422,6 +443,10 @@ CONFIG_SYMTAB_ORDEREDBYNAME=y # # Library Routines # + +# +# Standard C Library Options +# CONFIG_STDIO_BUFFER_SIZE=256 CONFIG_STDIO_LINEBUFFER=y CONFIG_NUNGET_CHARS=2 @@ -433,6 +458,7 @@ CONFIG_LIB_HOMEDIR="/" # CONFIG_EOL_IS_LF is not set # CONFIG_EOL_IS_BOTH_CRLF is not set CONFIG_EOL_IS_EITHER_CRLF=y +# CONFIG_LIBC_EXECFUNCS is not set # CONFIG_LIBC_STRERROR is not set # CONFIG_LIBC_PERROR_STDOUT is not set CONFIG_ARCH_LOWPUTC=y @@ -440,6 +466,11 @@ CONFIG_LIB_SENDFILE_BUFSIZE=512 # CONFIG_ARCH_ROMGETC is not set # CONFIG_ARCH_OPTIMIZED_FUNCTIONS is not set +# +# Non-standard Helper Functions +# +# CONFIG_LIB_KBDCODEC is not set + # # Basic CXX Support # @@ -458,9 +489,8 @@ CONFIG_HAVE_CXX=y # # -# Named Applications +# Built-In Applications # -# CONFIG_BUILTIN is not set # # Examples @@ -486,7 +516,6 @@ CONFIG_EXAMPLES_ELF_DEVPATH="/dev/ram0" # CONFIG_EXAMPLES_MM is not set # CONFIG_EXAMPLES_MOUNT is not set # CONFIG_EXAMPLES_MODBUS is not set -# CONFIG_EXAMPLES_NETTEST is not set # CONFIG_EXAMPLES_NSH is not set # CONFIG_EXAMPLES_NULL is not set # CONFIG_EXAMPLES_NX is not set @@ -501,6 +530,7 @@ CONFIG_EXAMPLES_ELF_DEVPATH="/dev/ram0" # CONFIG_EXAMPLES_PASHELLO is not set # CONFIG_EXAMPLES_PIPE is not set # CONFIG_EXAMPLES_POLL is not set +# CONFIG_EXAMPLES_POSIXSPAWN is not set # CONFIG_EXAMPLES_QENCODER is not set # CONFIG_EXAMPLES_RGMP is not set # CONFIG_EXAMPLES_ROMFS is not set @@ -516,7 +546,6 @@ CONFIG_EXAMPLES_ELF_DEVPATH="/dev/ram0" # CONFIG_EXAMPLES_USBMSC is not set # CONFIG_EXAMPLES_USBTERM is not set # CONFIG_EXAMPLES_WATCHDOG is not set -# CONFIG_EXAMPLES_WLAN is not set # # Interpreters diff --git a/configs/stm32f4discovery/posix_spawn/defconfig b/configs/stm32f4discovery/posix_spawn/defconfig index 9e30ada8a4a044fd35138607ab8039b0e4239f2d..97cf84ab463b9beff5c583a4af28bad1513fb550 100644 --- a/configs/stm32f4discovery/posix_spawn/defconfig +++ b/configs/stm32f4discovery/posix_spawn/defconfig @@ -279,6 +279,7 @@ CONFIG_DEV_CONSOLE=y CONFIG_SDCLONE_DISABLE=y # CONFIG_SCHED_WORKQUEUE is not set # CONFIG_SCHED_WAITPID is not set +CONFIG_SCHED_STARTHOOK=y # CONFIG_SCHED_ATEXIT is not set # CONFIG_SCHED_ONEXIT is not set CONFIG_USER_ENTRYPOINT="spawn_main" diff --git a/include/nuttx/sched.h b/include/nuttx/sched.h index 244455cd4ed1d0dff96a6b07c7fc92894f96b1c1..f8b4eb0dce1f140786a3b7c018dba128b6802528 100644 --- a/include/nuttx/sched.h +++ b/include/nuttx/sched.h @@ -183,7 +183,13 @@ union entry_u }; typedef union entry_u entry_t; -/* These is the types of the functions that are executed with exit() is called +/* This is the type of the function called at task startup */ + +#ifdef CONFIG_SCHED_STARTHOOK +typedef CODE void (*starthook_t)(FAR void *arg); +#endif + +/* These are the types of the functions that are executed with exit() is called * (if registered via atexit() on on_exit()). */ @@ -298,7 +304,10 @@ struct task_group_s #endif /* PIC data space and address environments ************************************/ - /* Not yet (see struct dspace_s) */ + /* Logically the PIC data space belongs here (see struct dspace_s). The + * current logic needs review: There are differences in the away that the + * life of the PIC data is managed. + */ /* File descriptors ***********************************************************/ @@ -354,6 +363,11 @@ struct _TCB start_t start; /* Thread start function */ entry_t entry; /* Entry Point into the thread */ +#ifdef CONFIG_SCHED_STARTHOOK + starthook_t starthook; /* Task startup function */ + FAR void *starthookarg; /* The argument passed to the function */ +#endif + #if defined(CONFIG_SCHED_ATEXIT) && !defined(CONFIG_SCHED_ONEXIT) # if defined(CONFIG_SCHED_ATEXIT_MAX) && CONFIG_SCHED_ATEXIT_MAX > 1 atexitfunc_t atexitfunc[CONFIG_SCHED_ATEXIT_MAX]; @@ -516,6 +530,12 @@ FAR struct streamlist *sched_getstreams(void); FAR struct socketlist *sched_getsockets(void); #endif /* CONFIG_NSOCKET_DESCRIPTORS */ +/* Setup up a start hook */ + +#ifdef CONFIG_SCHED_STARTHOOK +void task_starthook(FAR _TCB *tcb, starthook_t starthook, FAR void *arg); +#endif + /* Internal vfork support.The overall sequence is: * * 1) User code calls vfork(). vfork() is provided in architecture-specific diff --git a/sched/Kconfig b/sched/Kconfig index 7745c2c25efc67d7af76bcd2eed128db4ed07703..097dd19934d441ddefb896f8fe5bed3b06b6ba26 100644 --- a/sched/Kconfig +++ b/sched/Kconfig @@ -296,6 +296,16 @@ config SCHED_WAITPID compliant) and will enable the waitid() and wait() interfaces as well. +config SCHED_STARTHOOK + bool "Enable startup hook" + default n + ---help--- + Enable a non-standard, internal OS API call task_starthook(). + task_starthook() registers a function that will be called on task + startup before that actual task entry point is called. The + starthook is useful, for example, for setting up automatic + configuration of C++ constructors. + config SCHED_ATEXIT bool "Enable atexit() API" default n diff --git a/sched/Makefile b/sched/Makefile index 7710ae058841dacbfe96142715d4b094211ab0a3..9615601761f4a7038d25a66d9e96ce3dce824a5a 100644 --- a/sched/Makefile +++ b/sched/Makefile @@ -54,6 +54,10 @@ TSK_SRCS += task_posixspawn.c endif endif +ifeq ($(CONFIG_SCHED_STARTHOOK),y) +TSK_SRCS += task_starthook.c +endif + SCHED_SRCS = sched_setparam.c sched_setpriority.c sched_getparam.c SCHED_SRCS += sched_setscheduler.c sched_getscheduler.c SCHED_SRCS += sched_yield.c sched_rrgetinterval.c sched_foreach.c diff --git a/sched/group_setupidlefiles.c b/sched/group_setupidlefiles.c index 98cc7885e5b70c4ea6e169a371454d574bd7cd62..ceb9f3e2cbf82e9afaa978bb461e39251839439a 100644 --- a/sched/group_setupidlefiles.c +++ b/sched/group_setupidlefiles.c @@ -50,6 +50,7 @@ #include <nuttx/net/net.h> #include "os_internal.h" +#include "group_internal.h" #if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NSOCKET_DESCRIPTORS > 0 diff --git a/sched/group_setupstreams.c b/sched/group_setupstreams.c index 88e2662802c3171c06692e09b049fc5b82d1bccd..08399ae416938d594825cd06f480cb462ec479ad 100644 --- a/sched/group_setupstreams.c +++ b/sched/group_setupstreams.c @@ -46,6 +46,8 @@ #include <nuttx/net/net.h> #include <nuttx/lib.h> +#include "group_internal.h" + /* Make sure that there are file or socket descriptors in the system and * that some number of streams have been configured. */ diff --git a/sched/group_setuptaskfiles.c b/sched/group_setuptaskfiles.c index d52adcfeeae7614ced20f6f77d560414cdac447e..e2e7d4634f0fe68e0c578c9db7e9fe1d31bd568f 100644 --- a/sched/group_setuptaskfiles.c +++ b/sched/group_setuptaskfiles.c @@ -46,6 +46,7 @@ #include <nuttx/net/net.h> #include "os_internal.h" +#include "group_internal.h" #if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NSOCKET_DESCRIPTORS > 0 @@ -159,8 +160,8 @@ static inline void sched_dupsockets(FAR _TCB *tcb) /* Get pointers to the parent and child task socket lists */ - parent = rtcb->group->tg_sockets->sl_sockets; - child = tcb->group->tg_sockets->sl_sockets; + parent = rtcb->group->tg_socketlist.sl_sockets; + child = tcb->group->tg_socketlist.sl_sockets; /* Check each socket in the parent socket list */ diff --git a/sched/task_start.c b/sched/task_start.c index a9cc38dfcc29343515dab2ab3f30bc3946a3dbaf..5a32a5dd86d88820d6e020d3846f74ef21d06660 100644 --- a/sched/task_start.c +++ b/sched/task_start.c @@ -94,6 +94,15 @@ void task_start(void) FAR _TCB *tcb = (FAR _TCB*)g_readytorun.head; int argc; + /* Execute the start hook if one has been registered */ + +#ifdef CONFIG_SCHED_STARTHOOK + if (tcb->starthook) + { + tcb->starthook(tcb->starthookarg); + } +#endif + /* Count how many non-null arguments we are passing */ for (argc = 1; argc <= CONFIG_MAX_TASK_ARGS; argc++) diff --git a/sched/task_starthook.c b/sched/task_starthook.c new file mode 100644 index 0000000000000000000000000000000000000000..1cb29349fe660900498af3cf0fba02ea31734dac --- /dev/null +++ b/sched/task_starthook.c @@ -0,0 +1,100 @@ +/**************************************************************************** + * sched/task_start.c + * + * Copyright (C) 2007-2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <gnutt@nuttx.org> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <nuttx/sched.h> + +#ifdef CONFIG_SCHED_STARTHOOK + +/**************************************************************************** + * Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Type Declarations + ****************************************************************************/ + +/**************************************************************************** + * Global Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: task_starthook + * + * Description: + * Configure a start hook... a function that will be called on the thread + * of the new task before the new task's main entry point is called. + * The start hook is useful, for example, for setting up automatic + * configuration of C++ constructors. + * + * Inputs: + * tcb - The new, unstarted task task that needs the start hook + * starthook - The pointer to the start hook function + * arg - The argument to pass to the start hook function. + * + * Return: + * None + * + ****************************************************************************/ + +void task_starthook(FAR _TCB *tcb, starthook_t starthook, FAR void *arg) +{ + DEBUGASSERT(tcb); + tcb->starthook = starthook; + tcb->starthookarg = arg; +} + +#endif /* CONFIG_SCHED_STARTHOOK */