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:
patacongo
2011-05-28 21:42:18 +00:00
parent a155d4f576
commit ae8cfb1bf1
19 changed files with 334 additions and 115 deletions
+18 -3
View File
@@ -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.
+19 -3
View File
@@ -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 &lt;spudmonkey@racsa.co.cr&gt;
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 &quot;width&quot; 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 &lt;spudmonkey@racsa.co.cr&gt; apps-6.4 2011-xx-xx Gregory Nutt &lt;spudmonkey@racsa.co.cr&gt;
+12 -1
View File
@@ -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 &quot;width&quot; 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
+16 -17
View File
@@ -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)
+1 -1
View File
@@ -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;
} }
+8 -1
View File
@@ -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 */
+9
View File
@@ -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
+2 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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 */
+1
View File
@@ -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
View File
@@ -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
View File
@@ -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);
} }
+1
View File
@@ -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
View File
@@ -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 */
+157
View File
@@ -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
}