xiaoxiang781216 commented on code in PR #6197:
URL: https://github.com/apache/incubator-nuttx/pull/6197#discussion_r878660316


##########
include/nuttx/atexit.h:
##########
@@ -0,0 +1,81 @@
+/****************************************************************************
+ * include/nuttx/atexit.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __INCLUDE_SYS_ATEXIT_H

Review Comment:
   all __INCLUDE_SYS_ATEXIT_H to __INCLUDE_NUTTX_ATEXIT_H



##########
libs/libc/stdlib/lib_cxa_atexit.c:
##########
@@ -0,0 +1,80 @@
+/****************************************************************************
+ * libs/libc/stdlib/lib_cxa_atexit.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/atexit.h>
+#include <nuttx/compiler.h>
+#include <nuttx/lib/lib.h>
+
+#include <assert.h>
+#include <stdlib.h>
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+  FAR void *__dso_handle weak_data;

Review Comment:
   remove the space before FAR



##########
include/stdlib.h:
##########
@@ -81,6 +81,13 @@
 #define strtoll_l(s, e, b, l)  strtoll(s, e, b)
 #define strtoull_l(s, e, b, l) strtoull(s, e, b)
 
+/* Temporary fix for undefined exit() */
+
+#ifndef __KERNEL__
+#  undef  exit
+#  define exit nx_exit

Review Comment:
   But why not enable the compile of lib_exit?



##########
libs/libc/stdlib/lib_atexit.c:
##########
@@ -0,0 +1,217 @@
+/****************************************************************************
+ * libs/libc/stdlib/lib_atexit.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdlib.h>
+
+#include <nuttx/atexit.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/tls.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: get_exitfuncs
+ *
+ * Description:
+ *    Obtain the list of exit functions.
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   Pointer to the list of exit functions.
+ *
+ ****************************************************************************/
+
+FAR struct atexit_list_s * get_exitfuncs(void)
+{
+  FAR struct task_info_s *info;
+
+  info = task_get_info();
+  return &info->ta_exit;
+}
+
+/****************************************************************************
+ * Name: exitfunc_lock
+ *
+ * Description:
+ *    Obtain the exit function lock.
+ *
+ * Returned Value:
+ *   OK on success, or negated errno on failure
+ *
+ ****************************************************************************/
+
+int exitfunc_lock(void)

Review Comment:
   add static



##########
sched/task/exit.c:
##########
@@ -108,3 +106,8 @@ void exit(int status)
 
   _exit(status);
 }
+
+void exit(int status)

Review Comment:
   > It is this one I think:
   > 
   > ```
   > 
====================================================================================
   > Configuration/Tool: amber/hello
   > 
------------------------------------------------------------------------------------
   >  Cleaning...
   >  Configuring...
   >  Building NuttX...
   > /usr/lib/gcc/avr/5.4.0/avr51/libgcc.a(_exit.o): In function `_exit':
   > (.fini9+0x0): multiple definition of `_exit'
   > 
/github/workspace/sources/nuttx/staging/libsched.a(exit.o):exit.c:(.text+0x0): 
first defined here
   > make[1]: *** [Makefile:94: nuttx] Error 1
   > make: *** [tools/Unix.mk:509: nuttx] Error 2
   > make: Target 'all' not remade because of errors.
   > ```
   
   But I can't understand why the error doesn't report before, _exit in NuttX 
has been a long time, I think.
   
   > ```
   > /github/workspace/sources/nuttx/tools/testbuild.sh: line 257: 
/github/workspace/sources/nuttx/../nuttx/nuttx.manifest: No such file or 
directory
   >  Normalize amber/hello
   > ```
   > 
   > I think pulling _exit() from libgcc.a (the AVR compiler archive) is a 
problem anyway. Why is this archive even linked ? I have no idea.
   
   BTW, the implementation of _exit still exist in your patch, why the compiler 
doesn't complain the duplication now?



##########
libs/libc/stdlib/lib_atexit.c:
##########
@@ -0,0 +1,217 @@
+/****************************************************************************
+ * libs/libc/stdlib/lib_atexit.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdlib.h>
+
+#include <nuttx/atexit.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/tls.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: get_exitfuncs
+ *
+ * Description:
+ *    Obtain the list of exit functions.
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   Pointer to the list of exit functions.
+ *
+ ****************************************************************************/
+
+FAR struct atexit_list_s * get_exitfuncs(void)
+{
+  FAR struct task_info_s *info;
+
+  info = task_get_info();
+  return &info->ta_exit;
+}
+
+/****************************************************************************
+ * Name: exitfunc_lock
+ *
+ * Description:
+ *    Obtain the exit function lock.
+ *
+ * Returned Value:
+ *   OK on success, or negated errno on failure
+ *
+ ****************************************************************************/
+
+int exitfunc_lock(void)
+{
+  FAR struct task_info_s *info = task_get_info();
+  int ret = _SEM_WAIT(&info->ta_sem);
+
+  if (ret < 0)
+    {
+      ret = _SEM_ERRVAL(ret);
+    }
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: exitfunc_unlock
+ *
+ * Description:
+ *    Release exit function lock .
+ *
+ ****************************************************************************/
+
+void exitfunc_unlock(void)
+{
+  FAR struct task_info_s *info = task_get_info();
+
+  _SEM_POST(&info->ta_sem);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: atexit
+ *
+ * Description:
+ *    Registers a function to be called at program exit.
+ *    The atexit() function registers the given function to be called
+ *    at normal process termination, whether via exit or via return from
+ *    the program's main().
+ *
+ *    Limitations in the current implementation:
+ *
+ *      1. Only a single atexit function can be registered unless
+ *         CONFIG_LIBC_MAX_EXITFUNS defines a larger number.
+ *      2. atexit functions are not inherited when a new task is
+ *         created.
+ *
+ * Input Parameters:
+ *   func - A pointer to the function to be called when the task exits.
+ *
+ * Returned Value:
+ *   Zero on success. Non-zero on failure.
+ *
+ ****************************************************************************/
+
+int atexit(CODE void (*func)(void))
+{
+  return atexit_register(ATTYPE_ATEXIT, func, NULL, NULL);
+}
+
+int atexit_register(int type, CODE void (*func)(void), FAR void *arg,
+                      FAR void *dso)
+{
+  FAR struct atexit_list_s *aehead;
+  int                       idx;
+  int                       ret = ERROR;
+
+  /* REVISIT: Missing logic */
+
+  UNUSED(dso);
+
+  /* The following must be atomic */
+
+  aehead = get_exitfuncs();
+
+  if (func)
+    {
+      ret = exitfunc_lock();
+      if (ret < 0)
+        {
+          return ret;
+        }
+
+      if ((idx = aehead->next) < ATEXIT_MAX)
+        {
+          aehead->funcs[idx].type = type;
+          aehead->funcs[idx].func = func;
+          aehead->funcs[idx].arg  = arg;
+          aehead->next++;
+          ret = OK;
+        }
+
+      exitfunc_unlock();
+    }
+
+  return ret;
+}
+
+void atexit_call_exitfuncs(int status)
+{
+  FAR struct atexit_list_s *aehead;
+  FAR void                (*func)(void);

Review Comment:
   FAR to CODE



##########
libs/libc/stdlib/lib_onexit.c:
##########
@@ -0,0 +1,67 @@
+/****************************************************************************
+ * libs/libc/stdlib/lib_onexit.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/atexit.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: on_exit
+ *
+ * Description:
+ *    Registers a function to be called at program exit.
+ *    The on_exit() function registers the given function to be called
+ *    at normal process termination, whether via exit or via return from
+ *    the program's main(). The function is passed the status argument
+ *    given to the last call to exit and the arg argument from on_exit().
+ *
+ *    NOTE 1: This function comes from SunOS 4, but is also present in
+ *    libc4, libc5 and glibc. It no longer occurs in Solaris (SunOS 5).
+ *    Avoid this function, and use the standard atexit() instead.
+ *
+ *    Limitations in the current implementation:
+ *
+ *      1. Only a single on_exit function can be registered unless
+ *         CONFIG_LIBC_MAX_EXITFUNS defines a larger number.
+ *      2. on_exit functions are not inherited when a new task is
+ *         created.
+ *
+ * Input Parameters:
+ *   func - A pointer to the function to be called when the task exits.
+ *   arg -  An argument that will be provided to the on_exit() function when
+ *          the task exits.
+ *
+ * Returned Value:
+ *   Zero on success. Non-zero on failure.
+ *
+ ****************************************************************************/
+
+int on_exit(CODE void (*func)(int, FAR void *), FAR void *arg)
+{
+  return atexit_register(ATTYPE_ONEXIT, (void (*)(void))func, arg, NULL);

Review Comment:
   add CODE



##########
libs/libc/stdlib/lib_exit.c:
##########
@@ -39,9 +39,9 @@ void exit(int status)
 {
   atexit_call_exitfuncs(status);
 
-  /* REVISIT: Need to flush files and streams */
+  /* Call nx_exit() which will do the rest of the clean up and exit */
 
-  _exit(status);
+  nx_exit(status);

Review Comment:
   why change _exit to nx_exit?



##########
libs/libc/stdlib/lib_atexit.c:
##########
@@ -0,0 +1,217 @@
+/****************************************************************************
+ * libs/libc/stdlib/lib_atexit.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdlib.h>
+
+#include <nuttx/atexit.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/tls.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: get_exitfuncs
+ *
+ * Description:
+ *    Obtain the list of exit functions.
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   Pointer to the list of exit functions.
+ *
+ ****************************************************************************/
+
+FAR struct atexit_list_s * get_exitfuncs(void)
+{
+  FAR struct task_info_s *info;
+
+  info = task_get_info();
+  return &info->ta_exit;
+}
+
+/****************************************************************************
+ * Name: exitfunc_lock
+ *
+ * Description:
+ *    Obtain the exit function lock.
+ *
+ * Returned Value:
+ *   OK on success, or negated errno on failure
+ *
+ ****************************************************************************/
+
+int exitfunc_lock(void)
+{
+  FAR struct task_info_s *info = task_get_info();
+  int ret = _SEM_WAIT(&info->ta_sem);
+
+  if (ret < 0)
+    {
+      ret = _SEM_ERRVAL(ret);
+    }
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: exitfunc_unlock
+ *
+ * Description:
+ *    Release exit function lock .
+ *
+ ****************************************************************************/
+
+void exitfunc_unlock(void)
+{
+  FAR struct task_info_s *info = task_get_info();
+
+  _SEM_POST(&info->ta_sem);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: atexit
+ *
+ * Description:
+ *    Registers a function to be called at program exit.
+ *    The atexit() function registers the given function to be called
+ *    at normal process termination, whether via exit or via return from
+ *    the program's main().
+ *
+ *    Limitations in the current implementation:
+ *
+ *      1. Only a single atexit function can be registered unless
+ *         CONFIG_LIBC_MAX_EXITFUNS defines a larger number.
+ *      2. atexit functions are not inherited when a new task is
+ *         created.
+ *
+ * Input Parameters:
+ *   func - A pointer to the function to be called when the task exits.
+ *
+ * Returned Value:
+ *   Zero on success. Non-zero on failure.
+ *
+ ****************************************************************************/
+
+int atexit(CODE void (*func)(void))
+{
+  return atexit_register(ATTYPE_ATEXIT, func, NULL, NULL);
+}
+
+int atexit_register(int type, CODE void (*func)(void), FAR void *arg,
+                      FAR void *dso)
+{
+  FAR struct atexit_list_s *aehead;
+  int                       idx;
+  int                       ret = ERROR;
+
+  /* REVISIT: Missing logic */
+
+  UNUSED(dso);
+
+  /* The following must be atomic */
+
+  aehead = get_exitfuncs();
+
+  if (func)
+    {
+      ret = exitfunc_lock();
+      if (ret < 0)
+        {
+          return ret;
+        }
+
+      if ((idx = aehead->next) < ATEXIT_MAX)
+        {
+          aehead->funcs[idx].type = type;
+          aehead->funcs[idx].func = func;
+          aehead->funcs[idx].arg  = arg;
+          aehead->next++;
+          ret = OK;
+        }
+
+      exitfunc_unlock();
+    }
+
+  return ret;
+}
+
+void atexit_call_exitfuncs(int status)
+{
+  FAR struct atexit_list_s *aehead;
+  FAR void                (*func)(void);
+  FAR void                 *arg;
+  int                       idx;
+  int                       type;
+
+  /* Call exit functions in reverse order */
+
+  aehead = get_exitfuncs();
+
+  for (idx = aehead->next - 1; idx >= 0; idx--)
+    {
+      /* Remove the function to prevent recursive call to it */
+
+      type = aehead->funcs[idx].type;
+
+      func = aehead->funcs[idx].func;
+      arg  = aehead->funcs[idx].arg;
+
+      aehead->funcs[idx].func = NULL;
+      aehead->funcs[idx].arg  = NULL;
+
+      if (!func)
+        {
+          continue;
+        }
+
+      /* Call the atexit/on_exit/cxa_atexit() function */
+
+      if (type == ATTYPE_ATEXIT)
+        {
+          (*func)();
+        }
+      else if (type == ATTYPE_ONEXIT)
+        {
+          (*((void (*)(int, void *))func))(status, arg);
+        }
+      else if (type == ATTYPE_CXA)
+        {
+          (*((void (*)(void *))func))(arg);

Review Comment:
   (*((CODE void (*)(FAR void *))func))(arg);



##########
libs/libc/stdlib/lib_cxa_atexit.c:
##########
@@ -0,0 +1,80 @@
+/****************************************************************************
+ * libs/libc/stdlib/lib_cxa_atexit.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/atexit.h>
+#include <nuttx/compiler.h>
+#include <nuttx/lib/lib.h>
+
+#include <assert.h>
+#include <stdlib.h>
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif

Review Comment:
   don't need, this is c file



##########
libs/libc/stdlib/lib_cxa_atexit.c:
##########
@@ -0,0 +1,80 @@
+/****************************************************************************
+ * libs/libc/stdlib/lib_cxa_atexit.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/atexit.h>
+#include <nuttx/compiler.h>
+#include <nuttx/lib/lib.h>
+
+#include <assert.h>
+#include <stdlib.h>
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+  FAR void *__dso_handle weak_data;
+
+#if defined(__cplusplus)
+}
+#endif
+
+FAR void *__dso_handle = &__dso_handle;
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: __cxa_atexit
+ *
+ * Description:
+ *   __cxa_atexit() registers a destructor function to be called by exit().
+ *   On a call to exit(), the registered functions should be called with
+ *   the single argument 'arg'. Destructor functions shall always be
+ *   called in the reverse order to their registration (i.e. the most
+ *   recently registered function shall be called first),
+ *
+ *   If shared libraries were supported, the callbacks should be invoked
+ *   when the shared library is unloaded as well.
+ *
+ * Reference:
+ *   Linux base
+ *
+ ****************************************************************************/
+
+int __cxa_atexit(void (*func)(void *), FAR void *arg, FAR void *dso_handle)

Review Comment:
   add CODE before void?



##########
libs/libc/stdlib/lib_atexit.c:
##########
@@ -0,0 +1,217 @@
+/****************************************************************************
+ * libs/libc/stdlib/lib_atexit.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdlib.h>
+
+#include <nuttx/atexit.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/tls.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: get_exitfuncs
+ *
+ * Description:
+ *    Obtain the list of exit functions.
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   Pointer to the list of exit functions.
+ *
+ ****************************************************************************/
+
+FAR struct atexit_list_s * get_exitfuncs(void)
+{
+  FAR struct task_info_s *info;
+
+  info = task_get_info();
+  return &info->ta_exit;
+}
+
+/****************************************************************************
+ * Name: exitfunc_lock
+ *
+ * Description:
+ *    Obtain the exit function lock.
+ *
+ * Returned Value:
+ *   OK on success, or negated errno on failure
+ *
+ ****************************************************************************/
+
+int exitfunc_lock(void)
+{
+  FAR struct task_info_s *info = task_get_info();
+  int ret = _SEM_WAIT(&info->ta_sem);
+
+  if (ret < 0)
+    {
+      ret = _SEM_ERRVAL(ret);
+    }
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: exitfunc_unlock
+ *
+ * Description:
+ *    Release exit function lock .
+ *
+ ****************************************************************************/
+
+void exitfunc_unlock(void)

Review Comment:
   add static



##########
libs/libc/stdlib/lib_atexit.c:
##########
@@ -0,0 +1,217 @@
+/****************************************************************************
+ * libs/libc/stdlib/lib_atexit.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdlib.h>
+
+#include <nuttx/atexit.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/tls.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: get_exitfuncs
+ *
+ * Description:
+ *    Obtain the list of exit functions.
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   Pointer to the list of exit functions.
+ *
+ ****************************************************************************/
+
+FAR struct atexit_list_s * get_exitfuncs(void)
+{
+  FAR struct task_info_s *info;
+
+  info = task_get_info();
+  return &info->ta_exit;
+}
+
+/****************************************************************************
+ * Name: exitfunc_lock
+ *
+ * Description:
+ *    Obtain the exit function lock.
+ *
+ * Returned Value:
+ *   OK on success, or negated errno on failure
+ *
+ ****************************************************************************/
+
+int exitfunc_lock(void)
+{
+  FAR struct task_info_s *info = task_get_info();
+  int ret = _SEM_WAIT(&info->ta_sem);
+
+  if (ret < 0)
+    {
+      ret = _SEM_ERRVAL(ret);
+    }
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: exitfunc_unlock
+ *
+ * Description:
+ *    Release exit function lock .
+ *
+ ****************************************************************************/
+
+void exitfunc_unlock(void)
+{
+  FAR struct task_info_s *info = task_get_info();
+
+  _SEM_POST(&info->ta_sem);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: atexit
+ *
+ * Description:
+ *    Registers a function to be called at program exit.
+ *    The atexit() function registers the given function to be called
+ *    at normal process termination, whether via exit or via return from
+ *    the program's main().
+ *
+ *    Limitations in the current implementation:
+ *
+ *      1. Only a single atexit function can be registered unless
+ *         CONFIG_LIBC_MAX_EXITFUNS defines a larger number.
+ *      2. atexit functions are not inherited when a new task is
+ *         created.
+ *
+ * Input Parameters:
+ *   func - A pointer to the function to be called when the task exits.
+ *
+ * Returned Value:
+ *   Zero on success. Non-zero on failure.
+ *
+ ****************************************************************************/
+
+int atexit(CODE void (*func)(void))
+{
+  return atexit_register(ATTYPE_ATEXIT, func, NULL, NULL);
+}
+
+int atexit_register(int type, CODE void (*func)(void), FAR void *arg,
+                      FAR void *dso)
+{
+  FAR struct atexit_list_s *aehead;
+  int                       idx;
+  int                       ret = ERROR;
+
+  /* REVISIT: Missing logic */
+
+  UNUSED(dso);
+
+  /* The following must be atomic */
+
+  aehead = get_exitfuncs();
+
+  if (func)
+    {
+      ret = exitfunc_lock();
+      if (ret < 0)
+        {
+          return ret;
+        }
+
+      if ((idx = aehead->next) < ATEXIT_MAX)
+        {
+          aehead->funcs[idx].type = type;
+          aehead->funcs[idx].func = func;
+          aehead->funcs[idx].arg  = arg;
+          aehead->next++;
+          ret = OK;
+        }
+
+      exitfunc_unlock();
+    }
+
+  return ret;
+}
+
+void atexit_call_exitfuncs(int status)
+{
+  FAR struct atexit_list_s *aehead;
+  FAR void                (*func)(void);
+  FAR void                 *arg;
+  int                       idx;
+  int                       type;
+
+  /* Call exit functions in reverse order */
+
+  aehead = get_exitfuncs();
+
+  for (idx = aehead->next - 1; idx >= 0; idx--)
+    {
+      /* Remove the function to prevent recursive call to it */
+
+      type = aehead->funcs[idx].type;
+
+      func = aehead->funcs[idx].func;
+      arg  = aehead->funcs[idx].arg;
+
+      aehead->funcs[idx].func = NULL;
+      aehead->funcs[idx].arg  = NULL;
+
+      if (!func)
+        {
+          continue;
+        }
+
+      /* Call the atexit/on_exit/cxa_atexit() function */
+
+      if (type == ATTYPE_ATEXIT)
+        {
+          (*func)();
+        }
+      else if (type == ATTYPE_ONEXIT)
+        {
+          (*((void (*)(int, void *))func))(status, arg);

Review Comment:
   (*((CODE void (*)(int, FAR void *))func))(status, arg);



##########
libs/libc/stdlib/lib_cxa_atexit.c:
##########
@@ -0,0 +1,80 @@
+/****************************************************************************
+ * libs/libc/stdlib/lib_cxa_atexit.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/atexit.h>
+#include <nuttx/compiler.h>
+#include <nuttx/lib/lib.h>
+
+#include <assert.h>
+#include <stdlib.h>
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+  FAR void *__dso_handle weak_data;
+
+#if defined(__cplusplus)
+}
+#endif
+
+FAR void *__dso_handle = &__dso_handle;
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: __cxa_atexit
+ *
+ * Description:
+ *   __cxa_atexit() registers a destructor function to be called by exit().
+ *   On a call to exit(), the registered functions should be called with
+ *   the single argument 'arg'. Destructor functions shall always be
+ *   called in the reverse order to their registration (i.e. the most
+ *   recently registered function shall be called first),
+ *
+ *   If shared libraries were supported, the callbacks should be invoked
+ *   when the shared library is unloaded as well.
+ *
+ * Reference:
+ *   Linux base
+ *
+ ****************************************************************************/
+
+int __cxa_atexit(void (*func)(void *), FAR void *arg, FAR void *dso_handle)
+{
+  return atexit_register(ATTYPE_CXA, (void (*)(void))func, arg, dso_handle);

Review Comment:
   add CODE too



##########
sched/task/exit.c:
##########
@@ -70,7 +68,7 @@ void _exit(int status)
  *
  ****************************************************************************/
 
-void exit(int status)
+void nx_exit(int status)

Review Comment:
   Do we really need nx_exit? only _exit is really needed, I think.
   
   1. exit in libc call register exit function and flush/close file stream
   2. Continue the termination process by call _exit
   3. _exit in kernel release the rest resource
   
   So, we just need change exit at line 73 to _exit and remove line 101 finally.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscr...@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org

Reply via email to