mirror of
https://github.com/apache/nuttx.git
synced 2026-06-06 08:36:24 +08:00
atexit() functions now called when task killed by task delete; For MCUs with <= 64Kb of SRAM, CONFIG_MM_SMALL can be defined to reduce the memory allocation overhead
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3648 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
@@ -1548,7 +1548,7 @@
|
|||||||
* sched/atexit.c and sched/exit.c: The atexit function is not frequently
|
* sched/atexit.c and sched/exit.c: The atexit function is not frequently
|
||||||
used. In order to save a few bytes, it is now conditioned on
|
used. In order to save a few bytes, it is now conditioned on
|
||||||
CONFIG_SCHED_ATEXIT. It your application is currently using atexit(),
|
CONFIG_SCHED_ATEXIT. It your application is currently using atexit(),
|
||||||
you will need to add CONFIG_SCHED_ATEXT to your configuration file.
|
you will need to add CONFIG_SCHED_ATEXIT to your configuration file.
|
||||||
* drivers/net/slip.c: Add a SLIP driver (untested on initial check-in).
|
* drivers/net/slip.c: Add a SLIP driver (untested on initial check-in).
|
||||||
* configs/olimex-lpc1766stk/slip-httpd: An example that uses SLIP to
|
* configs/olimex-lpc1766stk/slip-httpd: An example that uses SLIP to
|
||||||
provide a serial-port based THTTPD web server.
|
provide a serial-port based THTTPD web server.
|
||||||
@@ -1770,7 +1770,22 @@
|
|||||||
the MPLAB debugger on PIC32; I will need to get a PICkit 3).
|
the MPLAB debugger on PIC32; I will need to get a PICkit 3).
|
||||||
* drivers/net/e1000.c/h: A PCI-based E1000 ethernet driver submitted
|
* drivers/net/e1000.c/h: A PCI-based E1000 ethernet driver submitted
|
||||||
by Yu Qiang.
|
by Yu Qiang.
|
||||||
* lib/net/lib_inetaddr.c: An implementatino of the inet_addr() function
|
* lib/net/lib_inetaddr.c: An implementation of the inet_addr() function
|
||||||
submitted y Yu Qiang.
|
submitted by Yu Qiang.
|
||||||
* arch/arm/src/lpc31xx and arch/arm/include/lpc31xx: Renamed from lpc313x
|
* arch/arm/src/lpc31xx and arch/arm/include/lpc31xx: Renamed from lpc313x
|
||||||
to make name space for other famiy members.
|
to make name space for other famiy members.
|
||||||
|
* arch/arm/*/lpc31xx: Added support for the LPC315x family (untested).
|
||||||
|
* sched/task_exithook.c: Functionality performed when a task exits or is
|
||||||
|
deleted has been moved to a common file task_exithook.c. Now exit()
|
||||||
|
functionality (like flushing I/O and calling registered atexit()
|
||||||
|
functions, etc.) will be performed when a task is deleted as well.
|
||||||
|
* mm/: Added support for CONFIG_MM_SMALL. Each memory allocation has a
|
||||||
|
small allocation overhead. The size of that overhead is normally
|
||||||
|
determined by the "width" of the address support by the MCU. MCUs
|
||||||
|
that support 16-bit addressability have smaller overhead than devices
|
||||||
|
that support 32-bit addressability. However, there are many MCUs
|
||||||
|
that support 32-bit addressability *but* have internal SRAM of size
|
||||||
|
less than or equal to 64Kb. In this case, CONFIG_MM_SMALL can be
|
||||||
|
defined so that those MCUs will also benefit from the smaller, 16-
|
||||||
|
bit-based allocation overhead.
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
<tr align="center" bgcolor="#e4e4e4">
|
<tr align="center" bgcolor="#e4e4e4">
|
||||||
<td>
|
<td>
|
||||||
<h1><big><font color="#3c34ec"><i>NuttX RTOS</i></font></big></h1>
|
<h1><big><font color="#3c34ec"><i>NuttX RTOS</i></font></big></h1>
|
||||||
<p>Last Updated: May 25, 2011</p>
|
<p>Last Updated: May 28, 2011</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
@@ -2313,8 +2313,24 @@ nuttx-6.4 2011-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
|
|||||||
the MPLAB debugger on PIC32; I will need to get a PICkit 3).
|
the MPLAB debugger on PIC32; I will need to get a PICkit 3).
|
||||||
* drivers/net/e1000.c/h: A PCI-based E1000 ethernet driver submitted
|
* drivers/net/e1000.c/h: A PCI-based E1000 ethernet driver submitted
|
||||||
by Yu Qiang.
|
by Yu Qiang.
|
||||||
* lib/net/lib_inetaddr.c: An implementatino of the inet_addr() function
|
* lib/net/lib_inetaddr.c: An implementation of the inet_addr() function
|
||||||
submitted y Yu Qiang.
|
submitted by Yu Qiang.
|
||||||
|
* arch/arm/src/lpc31xx and arch/arm/include/lpc31xx: Renamed from lpc313x
|
||||||
|
to make name space for other famiy members.
|
||||||
|
* arch/arm/*/lpc31xx: Added support for the LPC315x family (untested).
|
||||||
|
* sched/task_exithook.c: Functionality performed when a task exits or is
|
||||||
|
deleted has been moved to a common file task_exithook.c. Now exit()
|
||||||
|
functionality (like flushing I/O and calling registered atexit()
|
||||||
|
functions, etc.) will be performed when a task is deleted as well.
|
||||||
|
* mm/: Added support for CONFIG_MM_SMALL. Each memory allocation has a
|
||||||
|
small allocation overhead. The size of that overhead is normally
|
||||||
|
determined by the "width" of the address support by the MCU. MCUs
|
||||||
|
that support 16-bit addressability have smaller overhead than devices
|
||||||
|
that support 32-bit addressability. However, there are many MCUs
|
||||||
|
that support 32-bit addressability *but* have internal SRAM of size
|
||||||
|
less than or equal to 64Kb. In this case, CONFIG_MM_SMALL can be
|
||||||
|
defined so that those MCUs will also benefit from the smaller, 16-
|
||||||
|
bit-based allocation overhead.
|
||||||
|
|
||||||
apps-6.4 2011-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
|
apps-6.4 2011-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
<h1><big><font color="#3c34ec">
|
<h1><big><font color="#3c34ec">
|
||||||
<i>NuttX RTOS Porting Guide</i>
|
<i>NuttX RTOS Porting Guide</i>
|
||||||
</font></big></h1>
|
</font></big></h1>
|
||||||
<p>Last Updated: May 25, 2011</p>
|
<p>Last Updated: May 28, 2011</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
@@ -3262,6 +3262,17 @@ build
|
|||||||
number of memory regions that the memory manager must
|
number of memory regions that the memory manager must
|
||||||
handle and enables the API mm_addregion(start, end);
|
handle and enables the API mm_addregion(start, end);
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<code>CONFIG_MM_SMALL</code>: Each memory allocation has a small allocation
|
||||||
|
overhead. The size of that overhead is normally determined by
|
||||||
|
the "width" of the address support by the MCU. MCUs that support
|
||||||
|
16-bit addressability have smaller overhead than devices that
|
||||||
|
support 32-bit addressability. However, there are many MCUs
|
||||||
|
that support 32-bit addressability <i>but</i> have internal SRAM
|
||||||
|
of size less than or equal to 64Kb. In this case, CONFIG_MM_SMALL
|
||||||
|
can be defined so that those MCUs will also benefit from the
|
||||||
|
smaller, 16-bit-based allocation overhead.
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<code>CONFIG_MSEC_PER_TICK</code>: The default system timer is 100Hz
|
<code>CONFIG_MSEC_PER_TICK</code>: The default system timer is 100Hz
|
||||||
or <code>MSEC_PER_TICK</code>=10. This setting may be defined to inform NuttX
|
or <code>MSEC_PER_TICK</code>=10. This setting may be defined to inform NuttX
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
NuttX TODO List (Last updated May 14, 2011)
|
NuttX TODO List (Last updated May 28, 2011)
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
nuttx/
|
nuttx/
|
||||||
|
|
||||||
(5) Task/Scheduler (sched/)
|
(5) Task/Scheduler (sched/)
|
||||||
(1) On-demand paging (sched/)
|
(1) On-demand paging (sched/)
|
||||||
(2) Memory Managment (mm/)
|
(1) Memory Managment (mm/)
|
||||||
(1) Signals (sched/, arch/)
|
(1) Signals (sched/, arch/)
|
||||||
(1) pthreads (sched/)
|
(1) pthreads (sched/)
|
||||||
(1) C++ Support
|
(1) C++ Support
|
||||||
@@ -40,7 +40,7 @@ nuttx/
|
|||||||
apps/
|
apps/
|
||||||
|
|
||||||
(5) Network Utilities (apps/netutils/)
|
(5) Network Utilities (apps/netutils/)
|
||||||
(4) NuttShell (NSH) (apps/nshlib)
|
(5) NuttShell (NSH) (apps/nshlib)
|
||||||
(3) Other Applications & Tests (apps/examples/)
|
(3) Other Applications & Tests (apps/examples/)
|
||||||
|
|
||||||
o Task/Scheduler (sched/)
|
o Task/Scheduler (sched/)
|
||||||
@@ -51,13 +51,12 @@ o Task/Scheduler (sched/)
|
|||||||
Status: Open
|
Status: Open
|
||||||
Priority: Medium, required for good emulation of process/pthread model.
|
Priority: Medium, required for good emulation of process/pthread model.
|
||||||
|
|
||||||
Description: atexit() supports registration of one function called on exit().
|
Description: atexit() supports registration of only single function called on
|
||||||
Should task_delete() also cause atexit() function to be called?
|
exit(). It should support multiple functions registered by atexit()
|
||||||
Update: atexit() is only built into the system if CONFIG_SCHED_ATEXT
|
or onexit() and these should be called in reverse order of
|
||||||
is defined in the configuration.
|
registration when the task exits.
|
||||||
Status: Open
|
Status: Open
|
||||||
Priority: Low, task_delete() is non-standard and its behavior is
|
Priority: Low
|
||||||
unspecified.
|
|
||||||
|
|
||||||
Description: Implement sys/mman.h and functions
|
Description: Implement sys/mman.h and functions
|
||||||
Status: Open
|
Status: Open
|
||||||
@@ -121,13 +120,6 @@ o Memory Managment (mm/)
|
|||||||
Priority: Medium/Low, a good feature to prevent memory leaks but would
|
Priority: Medium/Low, a good feature to prevent memory leaks but would
|
||||||
have negative impact on memory usage and code size.
|
have negative impact on memory usage and code size.
|
||||||
|
|
||||||
Description: Current logic adapts size_t for 16-bit address machines vs.
|
|
||||||
32-bit address machines. But a small memory option should also
|
|
||||||
be provided so that the small offset option can be used with
|
|
||||||
32-bit machines that have small RAM memories (like the lpc2148)
|
|
||||||
Status: Open
|
|
||||||
Priority: High, a good feature enhancement.
|
|
||||||
|
|
||||||
o Signals (sched/, arch/)
|
o Signals (sched/, arch/)
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
@@ -329,7 +321,7 @@ o Network (net/, drivers/net)
|
|||||||
Description: The interfaces used to leave/join IGMP multicast groups is non-standard.
|
Description: The interfaces used to leave/join IGMP multicast groups is non-standard.
|
||||||
RFC3678 (IGMPv3) suggests ioctl() commands to do this (SIOCSIPMSFILTER) but
|
RFC3678 (IGMPv3) suggests ioctl() commands to do this (SIOCSIPMSFILTER) but
|
||||||
also status that those APIs are historic. NuttX implements these ioctl
|
also status that those APIs are historic. NuttX implements these ioctl
|
||||||
commnands, but is non-standard because: (1) It does not support IGMPv3, and
|
commands, but is non-standard because: (1) It does not support IGMPv3, and
|
||||||
(2) it looks up drivers by their device name (eg., "eth0") vs IP address.
|
(2) it looks up drivers by their device name (eg., "eth0") vs IP address.
|
||||||
|
|
||||||
Linux uses setsockopt() to control multicast group membership using the
|
Linux uses setsockopt() to control multicast group membership using the
|
||||||
@@ -1196,6 +1188,13 @@ o NuttShell (NSH) (apps/nshlib)
|
|||||||
Status: Open
|
Status: Open
|
||||||
Priority: Med-High
|
Priority: Med-High
|
||||||
|
|
||||||
|
Descripton: The ifconfig command will not behave correctly is an interface
|
||||||
|
is provided and there are multiple interfaces. It should only
|
||||||
|
show status for the single interface on the command line; it will
|
||||||
|
still show status for all interfaces.
|
||||||
|
Status: Open
|
||||||
|
Priority: Low (multiple network interfaces not fully supported yet anyway).
|
||||||
|
|
||||||
Description: Add support to NSH to run NXFLAT programs from a ROMFS file system
|
Description: Add support to NSH to run NXFLAT programs from a ROMFS file system
|
||||||
Status: Open
|
Status: Open
|
||||||
Priority: Low (enhancement)
|
Priority: Low (enhancement)
|
||||||
|
|||||||
@@ -81,5 +81,5 @@ static uint8_t sim_heap[SIM_HEAP_SIZE];
|
|||||||
void up_allocate_heap(void **heap_start, size_t *heap_size)
|
void up_allocate_heap(void **heap_start, size_t *heap_size)
|
||||||
{
|
{
|
||||||
*heap_start = sim_heap;
|
*heap_start = sim_heap;
|
||||||
*heap_size = SIM_HEAP_SIZE;
|
*heap_size = SIM_HEAP_SIZE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,7 @@
|
|||||||
* Included Files
|
* Included Files
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <nuttx/irq.h>
|
#include <nuttx/irq.h>
|
||||||
|
|
||||||
@@ -64,7 +65,13 @@
|
|||||||
# define JB_PC (5)
|
# define JB_PC (5)
|
||||||
#endif /* __ASSEMBLY__ */
|
#endif /* __ASSEMBLY__ */
|
||||||
|
|
||||||
#define SIM_HEAP_SIZE (4*1024*1024)
|
/* Size of the simulated heap */
|
||||||
|
|
||||||
|
#if CONFIG_MM_SMALL
|
||||||
|
# define SIM_HEAP_SIZE (64*1024)
|
||||||
|
#else
|
||||||
|
# define SIM_HEAP_SIZE (4*1024*1024)
|
||||||
|
#endif
|
||||||
|
|
||||||
/* These definitions characterize the compressed filesystem image */
|
/* These definitions characterize the compressed filesystem image */
|
||||||
|
|
||||||
|
|||||||
@@ -261,6 +261,15 @@ defconfig -- This is a configuration file similar to the Linux
|
|||||||
regions of memory to allocate from, this specifies the
|
regions of memory to allocate from, this specifies the
|
||||||
number of memory regions that the memory manager must
|
number of memory regions that the memory manager must
|
||||||
handle and enables the API mm_addregion(start, end);
|
handle and enables the API mm_addregion(start, end);
|
||||||
|
CONFIG_MM_SMALL - Each memory allocation has a small allocation
|
||||||
|
overhead. The size of that overhead is normally determined by
|
||||||
|
the "width" of the address support by the MCU. MCUs that support
|
||||||
|
16-bit addressability have smaller overhead than devices that
|
||||||
|
support 32-bit addressability. However, there are many MCUs
|
||||||
|
that support 32-bit addressability *but* have internal SRAM
|
||||||
|
of size less than or equal to 64Kb. In this case, CONFIG_MM_SMALL
|
||||||
|
can be defined so that those MCUs will also benefit from the
|
||||||
|
smaller, 16-bit-based allocation overhead.
|
||||||
CONFIG_MSEC_PER_TICK - The default system timer is 100Hz
|
CONFIG_MSEC_PER_TICK - The default system timer is 100Hz
|
||||||
or MSEC_PER_TICK=10. This setting may be defined to
|
or MSEC_PER_TICK=10. This setting may be defined to
|
||||||
inform NuttX that the processor hardware is providing
|
inform NuttX that the processor hardware is providing
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ typedef union entry_u entry_t;
|
|||||||
* (if registered via atexit()).
|
* (if registered via atexit()).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef CONFIG_SCHED_ATEXT
|
#ifdef CONFIG_SCHED_ATEXIT
|
||||||
typedef void (*exitfunc_t)(void);
|
typedef void (*exitfunc_t)(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -184,7 +184,7 @@ struct _TCB
|
|||||||
pid_t pid; /* This is the ID of the thread */
|
pid_t pid; /* This is the ID of the thread */
|
||||||
start_t start; /* Thread start function */
|
start_t start; /* Thread start function */
|
||||||
entry_t entry; /* Entry Point into the thread */
|
entry_t entry; /* Entry Point into the thread */
|
||||||
#ifdef CONFIG_SCHED_ATEXT
|
#ifdef CONFIG_SCHED_ATEXIT
|
||||||
exitfunc_t exitfunc; /* Called if exit is called. */
|
exitfunc_t exitfunc; /* Called if exit is called. */
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_SCHED_WAITPID /* Experimental */
|
#ifdef CONFIG_SCHED_WAITPID /* Experimental */
|
||||||
|
|||||||
+2
-1
@@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* mm/mm_environment.h
|
* mm/mm_environment.h
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -76,6 +76,7 @@
|
|||||||
# define FAR /* Normally in compiler.h */
|
# define FAR /* Normally in compiler.h */
|
||||||
# define CONFIG_CPP_HAVE_VARARGS 1 /* Normally in compiler.h */
|
# define CONFIG_CPP_HAVE_VARARGS 1 /* Normally in compiler.h */
|
||||||
# define CONFIG_MM_REGIONS 2 /* Normally in config.h */
|
# define CONFIG_MM_REGIONS 2 /* Normally in config.h */
|
||||||
|
# undef CONFIG_MM_SMALL /* Normally in config.h */
|
||||||
# define CONFIG_CAN_PASS_STRUCTS 1 /* Normally in config.h */
|
# define CONFIG_CAN_PASS_STRUCTS 1 /* Normally in config.h */
|
||||||
# undef CONFIG_SMALL_MEMORY /* Normally in config.h */
|
# undef CONFIG_SMALL_MEMORY /* Normally in config.h */
|
||||||
|
|
||||||
|
|||||||
+15
-6
@@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* mm/mm_initialize.c
|
* mm/mm_initialize.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -124,7 +124,7 @@ void mm_initialize(FAR void *heapstart, size_t heapsize)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize the malloc semaphore to one (to support one-at-
|
/* Initialize the malloc semaphore to one (to support one-at-
|
||||||
* a-time access to private data sets.
|
* a-time access to private data sets).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
mm_seminitialize();
|
mm_seminitialize();
|
||||||
@@ -155,20 +155,29 @@ void mm_initialize(FAR void *heapstart, size_t heapsize)
|
|||||||
void mm_addregion(FAR void *heapstart, size_t heapsize)
|
void mm_addregion(FAR void *heapstart, size_t heapsize)
|
||||||
{
|
{
|
||||||
FAR struct mm_freenode_s *node;
|
FAR struct mm_freenode_s *node;
|
||||||
size_t heapbase;
|
uintptr_t heapbase;
|
||||||
size_t heapend;
|
uintptr_t heapend;
|
||||||
#if CONFIG_MM_REGIONS > 1
|
#if CONFIG_MM_REGIONS > 1
|
||||||
int IDX = g_nregions;
|
int IDX = g_nregions;
|
||||||
#else
|
#else
|
||||||
# define IDX 0
|
# define IDX 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* If the MCU handles wide addresses but the memory manager
|
||||||
|
* is configured for a small heap, then verify that the caller
|
||||||
|
* not doing something crazy.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(CONFIG_MM_SMALL) && !defined(CONFIG_SMALL_MEMORY)
|
||||||
|
DEBUGASSERT(heapsize <= MMSIZE_MAX+1);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Adjust the provide heap start and size so that they are
|
/* Adjust the provide heap start and size so that they are
|
||||||
* both aligned with the MM_MIN_CHUNK size.
|
* both aligned with the MM_MIN_CHUNK size.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
heapbase = MM_ALIGN_UP((size_t)heapstart);
|
heapbase = MM_ALIGN_UP((uintptr_t)heapstart);
|
||||||
heapend = MM_ALIGN_DOWN((size_t)heapstart + (size_t)heapsize);
|
heapend = MM_ALIGN_DOWN((uintptr_t)heapstart + (uintptr_t)heapsize);
|
||||||
heapsize = heapend - heapbase;
|
heapsize = heapend - heapbase;
|
||||||
|
|
||||||
mlldbg("Region %d: base=%p size=%u\n", IDX+1, heapstart, heapsize);
|
mlldbg("Region %d: base=%p size=%u\n", IDX+1, heapstart, heapsize);
|
||||||
|
|||||||
+50
-14
@@ -1,7 +1,7 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
* mm/mm_internal.h
|
* mm/mm_internal.h
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -43,7 +43,24 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Pre-processor Definitions
|
* Pre-processor Definitions
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
/* Configuration ********************************************************/
|
||||||
|
/* If the MCU has a small (16-bit) address capability, then we will use
|
||||||
|
* a smaller chunk header that contains 16-bit size/offset information.
|
||||||
|
* We will also use the smaller header on MCUs with wider addresses if
|
||||||
|
* CONFIG_MM_SMALL is selected. This configuration is common with MCUs
|
||||||
|
* that have a large FLASH space, but only a tiny internal SRAM.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef CONFIG_SMALL_MEMORY
|
||||||
|
/* If the MCU has a small addressing capability, then for the smaller
|
||||||
|
* chunk header.
|
||||||
|
*/
|
||||||
|
|
||||||
|
# undef CONFIG_MM_SMALL
|
||||||
|
# define CONFIG_MM_SMALL 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Chunk Header Definitions *********************************************/
|
||||||
/* These definitions define the characteristics of allocator
|
/* These definitions define the characteristics of allocator
|
||||||
*
|
*
|
||||||
* MM_MIN_SHIFT is used to define MM_MIN_CHUNK.
|
* MM_MIN_SHIFT is used to define MM_MIN_CHUNK.
|
||||||
@@ -61,7 +78,7 @@
|
|||||||
* losses.
|
* losses.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef CONFIG_SMALL_MEMORY
|
#ifdef CONFIG_MM_SMALL
|
||||||
# define MM_MIN_SHIFT 4 /* 16 bytes */
|
# define MM_MIN_SHIFT 4 /* 16 bytes */
|
||||||
# define MM_MAX_SHIFT 15 /* 32 Kb */
|
# define MM_MAX_SHIFT 15 /* 32 Kb */
|
||||||
#else
|
#else
|
||||||
@@ -84,7 +101,7 @@
|
|||||||
* an allocated chunk.
|
* an allocated chunk.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef CONFIG_SMALL_MEMORY
|
#ifdef CONFIG_MM_SMALL
|
||||||
# define MM_ALLOC_BIT 0x8000
|
# define MM_ALLOC_BIT 0x8000
|
||||||
#else
|
#else
|
||||||
# define MM_ALLOC_BIT 0x80000000
|
# define MM_ALLOC_BIT 0x80000000
|
||||||
@@ -96,18 +113,30 @@
|
|||||||
* Public Types
|
* Public Types
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
|
||||||
|
/* Determine the size of the chunk size/offset type */
|
||||||
|
|
||||||
|
#ifdef CONFIG_MM_SMALL
|
||||||
|
typedef uint16_t mmsize_t;
|
||||||
|
# define MMSIZE_MAX 0xffff
|
||||||
|
#else
|
||||||
|
typedef size_t mmsize_t;
|
||||||
|
# define MMSIZE_MAX SIZE_MAX
|
||||||
|
#endif
|
||||||
|
|
||||||
/* This describes an allocated chunk. An allocated chunk is
|
/* This describes an allocated chunk. An allocated chunk is
|
||||||
* distinguished from a free chunk by bit 31 of the 'precding'
|
* distinguished from a free chunk by bit 15/31 of the 'preceding' chunk
|
||||||
* chunk size. If set, then this is an allocated chunk.
|
* size. If set, then this is an allocated chunk.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct mm_allocnode_s
|
struct mm_allocnode_s
|
||||||
{
|
{
|
||||||
size_t size; /* Size of this chunk */
|
mmsize_t size; /* Size of this chunk */
|
||||||
size_t preceding; /* Size of the preceding chunk */
|
mmsize_t preceding; /* Size of the preceding chunk */
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_SMALL_MEMORY
|
/* What is the size of the allocnode? */
|
||||||
|
|
||||||
|
#ifdef CONFIG_MM_SMALL
|
||||||
# define SIZEOF_MM_ALLOCNODE 4
|
# define SIZEOF_MM_ALLOCNODE 4
|
||||||
#else
|
#else
|
||||||
# define SIZEOF_MM_ALLOCNODE 8
|
# define SIZEOF_MM_ALLOCNODE 8
|
||||||
@@ -120,18 +149,25 @@ struct mm_allocnode_s
|
|||||||
|
|
||||||
struct mm_freenode_s
|
struct mm_freenode_s
|
||||||
{
|
{
|
||||||
size_t size; /* Size of this chunk */
|
mmsize_t size; /* Size of this chunk */
|
||||||
size_t preceding; /* Size of the preceding chunk */
|
mmsize_t preceding; /* Size of the preceding chunk */
|
||||||
FAR struct mm_freenode_s *flink; /* Supports a doubly linked list */
|
FAR struct mm_freenode_s *flink; /* Supports a doubly linked list */
|
||||||
FAR struct mm_freenode_s *blink;
|
FAR struct mm_freenode_s *blink;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_SMALL_MEMORY
|
/* Free is the size of the freenode */
|
||||||
# define SIZEOF_MM_FREENODE 8
|
|
||||||
|
#ifdef CONFIG_MM_SMALL
|
||||||
|
# ifdef CONFIG_SMALL_MEMORY
|
||||||
|
# define SIZEOF_MM_FREENODE 8
|
||||||
|
# else
|
||||||
|
# define SIZEOF_MM_FREENODE 12
|
||||||
|
# endif
|
||||||
#else
|
#else
|
||||||
# define SIZEOF_MM_FREENODE 16
|
# define SIZEOF_MM_FREENODE 16
|
||||||
#endif
|
#endif
|
||||||
#define CHECK_FREENODE_SIZE \
|
|
||||||
|
#define CHECK_FREENODE_SIZE \
|
||||||
DEBUGASSERT(sizeof(struct mm_freenode_s) == SIZEOF_MM_FREENODE)
|
DEBUGASSERT(sizeof(struct mm_freenode_s) == SIZEOF_MM_FREENODE)
|
||||||
|
|
||||||
/* Normally defined in stdlib.h */
|
/* Normally defined in stdlib.h */
|
||||||
|
|||||||
+1
-1
@@ -199,6 +199,6 @@ FAR void *malloc(size_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
mm_givesemaphore();
|
mm_givesemaphore();
|
||||||
mvdbg("Allocated %p\n", ret);
|
mvdbg("Allocated %p, size %d\n", ret, size);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -94,7 +94,7 @@ FAR void *memalign(size_t alignment, size_t size)
|
|||||||
* The do not include SIZEOF_MM_ALLOCNODE.
|
* The do not include SIZEOF_MM_ALLOCNODE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
size = MM_ALIGN_UP(size); /* Make mutliples of our granule size */
|
size = MM_ALIGN_UP(size); /* Make multiples of our granule size */
|
||||||
allocsize = size + 2*alignment; /* Add double full alignment size */
|
allocsize = size + 2*alignment; /* Add double full alignment size */
|
||||||
|
|
||||||
/* Then malloc that size */
|
/* Then malloc that size */
|
||||||
|
|||||||
@@ -41,6 +41,7 @@
|
|||||||
|
|
||||||
#define FAR
|
#define FAR
|
||||||
#define CONFIG_MM_REGIONS 2
|
#define CONFIG_MM_REGIONS 2
|
||||||
|
#undef CONFIG_MM_SMALL
|
||||||
#define CONFIG_CAN_PASS_STRUCTS 1
|
#define CONFIG_CAN_PASS_STRUCTS 1
|
||||||
#undef CONFIG_SMALL_MEMORY
|
#undef CONFIG_SMALL_MEMORY
|
||||||
|
|
||||||
|
|||||||
+5
-5
@@ -44,11 +44,11 @@ MISC_SRCS = os_start.c os_bringup.c errno_getptr.c errno_get.c errno_set.c \
|
|||||||
sched_setuppthreadfiles.c sched_releasefiles.c
|
sched_setuppthreadfiles.c sched_releasefiles.c
|
||||||
|
|
||||||
TSK_SRCS = task_create.c task_init.c task_setup.c task_activate.c \
|
TSK_SRCS = task_create.c task_init.c task_setup.c task_activate.c \
|
||||||
task_start.c task_delete.c task_deletecurrent.c task_restart.c \
|
task_start.c task_delete.c task_deletecurrent.c task_exithook.c \
|
||||||
exit.c atexit.c getpid.c sched_addreadytorun.c sched_removereadytorun.c \
|
task_restart.c exit.c atexit.c getpid.c sched_addreadytorun.c \
|
||||||
sched_addprioritized.c sched_mergepending.c sched_addblocked.c \
|
sched_removereadytorun.c sched_addprioritized.c sched_mergepending.c \
|
||||||
sched_removeblocked.c sched_free.c sched_gettcb.c sched_verifytcb.c \
|
sched_addblocked.c sched_removeblocked.c sched_free.c sched_gettcb.c \
|
||||||
sched_releasetcb.c
|
sched_verifytcb.c sched_releasetcb.c
|
||||||
|
|
||||||
SCHED_SRCS = sched_setparam.c sched_setpriority.c sched_getparam.c \
|
SCHED_SRCS = sched_setparam.c sched_setpriority.c sched_getparam.c \
|
||||||
sched_setscheduler.c sched_getscheduler.c \
|
sched_setscheduler.c sched_getscheduler.c \
|
||||||
|
|||||||
+10
-49
@@ -67,7 +67,7 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Functionss
|
* Private Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -78,68 +78,29 @@
|
|||||||
* Function: exit
|
* Function: exit
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* The exit() function causes normal process termination
|
* The exit() function causes normal process termination and the value of
|
||||||
* and the value of status & 0377 is returned to the parent.
|
* status & 0377 to be returned to the parent.
|
||||||
*
|
*
|
||||||
* All functions registered with atexit() and on_exit() are
|
* All functions registered with atexit() and on_exit() are called, in the
|
||||||
* called, in the reverse order of their registration.
|
* reverse order of their registration.
|
||||||
*
|
*
|
||||||
* All open streams are flushed and closed. Files created
|
* All open streams are flushed and closed.
|
||||||
* by tmpfile() are removed.
|
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
void exit(int status)
|
void exit(int status)
|
||||||
{
|
{
|
||||||
#if CONFIG_NFILE_STREAMS > 0 || defined(CONFIG_SCHED_WAITPID) || defined(CONFIG_SCHED_ATEXIT)
|
|
||||||
_TCB *tcb = (_TCB*)g_readytorun.head;
|
_TCB *tcb = (_TCB*)g_readytorun.head;
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Only the lower 8 bits of the exit status are used */
|
/* Only the lower 8-bits of status are used */
|
||||||
|
|
||||||
status &= 0xff;
|
status &= 0xff;
|
||||||
|
|
||||||
/* Flush all streams (File descriptors will be closed when
|
/* Perform common task termination logic */
|
||||||
* the TCB is deallocated.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if CONFIG_NFILE_STREAMS > 0
|
task_exithook(tcb, status);
|
||||||
(void)lib_flushall(tcb->streams);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Wakeup any tasks waiting for this task to exit */
|
/* Then "really" exit. Only the lower 8 bits of the exit status are used. */
|
||||||
|
|
||||||
#ifdef CONFIG_SCHED_WAITPID /* Experimental */
|
|
||||||
while (tcb->exitsem.semcount < 0)
|
|
||||||
{
|
|
||||||
/* "If more than one thread is suspended in waitpid() awaiting
|
|
||||||
* termination of the same process, exactly one thread will return
|
|
||||||
* the process status at the time of the target process termination."
|
|
||||||
* Hmmm.. what do we return to the others?
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (tcb->stat_loc)
|
|
||||||
{
|
|
||||||
*tcb->stat_loc = status << 8;
|
|
||||||
tcb->stat_loc = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Wake up the thread */
|
|
||||||
|
|
||||||
sem_post(&tcb->exitsem);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* If an exit function was registered, call it now. */
|
|
||||||
|
|
||||||
#ifdef CONFIG_SCHED_ATEXIT
|
|
||||||
if (tcb->exitfunc)
|
|
||||||
{
|
|
||||||
(*tcb->exitfunc)();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Then "really" exit */
|
|
||||||
|
|
||||||
_exit(status);
|
_exit(status);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -265,6 +265,7 @@ extern void task_start(void);
|
|||||||
extern int task_schedsetup(FAR _TCB *tcb, int priority, start_t start,
|
extern int task_schedsetup(FAR _TCB *tcb, int priority, start_t start,
|
||||||
main_t main);
|
main_t main);
|
||||||
extern int task_argsetup(FAR _TCB *tcb, const char *name, const char *argv[]);
|
extern int task_argsetup(FAR _TCB *tcb, const char *name, const char *argv[]);
|
||||||
|
extern void task_exithook(FAR _TCB *tcb, int status);
|
||||||
extern int task_deletecurrent(void);
|
extern int task_deletecurrent(void);
|
||||||
#ifndef CONFIG_CUSTOM_STACK
|
#ifndef CONFIG_CUSTOM_STACK
|
||||||
extern int kernel_thread(const char *name, int priority,
|
extern int kernel_thread(const char *name, int priority,
|
||||||
|
|||||||
+6
-10
@@ -140,14 +140,9 @@ int task_delete(pid_t pid)
|
|||||||
PANIC(OSERR_BADDELETESTATE);
|
PANIC(OSERR_BADDELETESTATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
saved_state = irqsave();
|
|
||||||
|
|
||||||
/* Inform the instrumentation layer that the task has stopped */
|
|
||||||
|
|
||||||
sched_note_stop(dtcb);
|
|
||||||
|
|
||||||
/* Remove the task from the OS's tasks lists. */
|
/* Remove the task from the OS's tasks lists. */
|
||||||
|
|
||||||
|
saved_state = irqsave();
|
||||||
dq_rem((FAR dq_entry_t*)dtcb, (dq_queue_t*)g_tasklisttable[dtcb->task_state].list);
|
dq_rem((FAR dq_entry_t*)dtcb, (dq_queue_t*)g_tasklisttable[dtcb->task_state].list);
|
||||||
dtcb->task_state = TSTATE_TASK_INVALID;
|
dtcb->task_state = TSTATE_TASK_INVALID;
|
||||||
irqrestore(saved_state);
|
irqrestore(saved_state);
|
||||||
@@ -156,11 +151,12 @@ int task_delete(pid_t pid)
|
|||||||
|
|
||||||
sched_unlock();
|
sched_unlock();
|
||||||
|
|
||||||
/* Deallocate anything left in the TCB's queues */
|
/* Perform common task termination logic (flushing streams, calling
|
||||||
|
* functions registered by at_exit/on_exit, etc.). I suppose EXIT_SUCCESS
|
||||||
|
* is an appropriate return value???
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef CONFIG_DISABLE_SIGNALS
|
task_exithook(dtcb, EXIT_SUCCESS);
|
||||||
sig_cleanup(dtcb); /* Deallocate Signal lists */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Deallocate its TCB */
|
/* Deallocate its TCB */
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,157 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* sched/task_exithook.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
||||||
|
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||||
|
*
|
||||||
|
* 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 <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <debug.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <nuttx/fs.h>
|
||||||
|
|
||||||
|
#include "os_internal.h"
|
||||||
|
#include "sig_internal.h"
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Definitions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Type Declarations
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Global Variables
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Variables
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Function Prototypes
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Function: task_hook
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* This function implements some of the internal logic of exit() and
|
||||||
|
* task_delete(). This function performs some cleanup and other actions
|
||||||
|
* required when a task exists:
|
||||||
|
*
|
||||||
|
* - All open streams are flushed and closed.
|
||||||
|
* - All functions registered with atexit() and on_exit() are called, in
|
||||||
|
* the reverse order of their registration.
|
||||||
|
*
|
||||||
|
* When called from exit(), the tcb still resides at the head of the ready-
|
||||||
|
* to-run list. The following logic is safe because we will not be
|
||||||
|
* returning from the exit() call.
|
||||||
|
*
|
||||||
|
* When called from task_delete() we are operating on a different thread;
|
||||||
|
* on the thread that called task_delete(). In this case, task_delete
|
||||||
|
* will have already removed the tcb from the ready-to-run list to prevent
|
||||||
|
* any further action on this task.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void task_exithook(FAR _TCB *tcb, int status)
|
||||||
|
{
|
||||||
|
/* Inform the instrumentation layer that the task has stopped */
|
||||||
|
|
||||||
|
sched_note_stop(tcb);
|
||||||
|
|
||||||
|
/* Flush all streams (File descriptors will be closed when
|
||||||
|
* the TCB is deallocated).
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if CONFIG_NFILE_STREAMS > 0
|
||||||
|
(void)lib_flushall(tcb->streams);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Deallocate anything left in the TCB's queues */
|
||||||
|
|
||||||
|
#ifndef CONFIG_DISABLE_SIGNALS
|
||||||
|
sig_cleanup(tcb); /* Deallocate Signal lists */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Wakeup any tasks waiting for this task to exit */
|
||||||
|
|
||||||
|
#ifdef CONFIG_SCHED_WAITPID /* Experimental */
|
||||||
|
while (tcb->exitsem.semcount < 0)
|
||||||
|
{
|
||||||
|
/* "If more than one thread is suspended in waitpid() awaiting
|
||||||
|
* termination of the same process, exactly one thread will return
|
||||||
|
* the process status at the time of the target process termination."
|
||||||
|
* Hmmm.. what do we return to the others?
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (tcb->stat_loc)
|
||||||
|
{
|
||||||
|
*tcb->stat_loc = status << 8;
|
||||||
|
tcb->stat_loc = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wake up the thread */
|
||||||
|
|
||||||
|
sem_post(&tcb->exitsem);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* If an exit function was registered, call it now. NOTE: In the case
|
||||||
|
* of task_delete(), the exit function will *not* be called on the thread
|
||||||
|
* execution of the task being deleted!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef CONFIG_SCHED_ATEXIT
|
||||||
|
if (tcb->exitfunc)
|
||||||
|
{
|
||||||
|
(*tcb->exitfunc)();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user