mirror of
https://github.com/apache/nuttx.git
synced 2026-05-26 10:46:28 +08:00
Add a start hook that can be setup to call a function in the context of a new thread before the new threads main() has been called.
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5571 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
+23
-38
@@ -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
|
||||
|
||||
/* 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
|
||||
task_starthook(tcb, exec_ctors, (FAR void *)binp);
|
||||
#endif
|
||||
|
||||
/* Get the assigned pid before we start the task */
|
||||
|
||||
pid = tcb->pid;
|
||||
|
||||
/* Execute all of the C++ static constructors */
|
||||
|
||||
#ifdef CONFIG_BINFMT_CONSTRUCTORS
|
||||
ret = exec_ctors(binp);
|
||||
if (ret < 0)
|
||||
{
|
||||
err = -ret;
|
||||
bdbg("exec_ctors() failed: %d\n", ret);
|
||||
goto errout_with_stack;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Then activate the task at the provided priority */
|
||||
|
||||
ret = task_activate(tcb);
|
||||
|
||||
Reference in New Issue
Block a user