You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by da...@apache.org on 2021/06/18 12:44:48 UTC

[incubator-nuttx] branch master updated: sched: Identify the stack need to free by TCB_FLAG_FREE_STACK

This is an automated email from the ASF dual-hosted git repository.

davids5 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new ab974ed  sched: Identify the stack need to free by TCB_FLAG_FREE_STACK
ab974ed is described below

commit ab974edc84e753782288f3b819e6358e9bb8fe0d
Author: Xiang Xiao <xi...@xiaomi.com>
AuthorDate: Mon Jun 14 02:08:34 2021 +0800

    sched: Identify the stack need to free by TCB_FLAG_FREE_STACK
    
    instead calling kmm_heapmember or umm_heapmember because:
    1.The stack supplied by caller may allocate from heap too
    2.It's hard to implement these two function in ASan case
    
    Signed-off-by: Xiang Xiao <xi...@xiaomi.com>
    Change-Id: I196377822b7c4643ab4f29b7c1dc41dcd7c4dab1
---
 arch/arm/src/common/arm_createstack.c         |  3 ++-
 arch/arm/src/common/arm_releasestack.c        | 21 +++++++--------------
 arch/arm/src/common/arm_usestack.c            |  2 +-
 arch/avr/src/avr/up_createstack.c             |  3 ++-
 arch/avr/src/avr/up_usestack.c                |  2 +-
 arch/avr/src/avr32/up_createstack.c           |  3 ++-
 arch/avr/src/avr32/up_usestack.c              |  2 +-
 arch/avr/src/common/up_releasestack.c         | 21 +++++++--------------
 arch/hc/src/common/up_createstack.c           |  3 ++-
 arch/hc/src/common/up_releasestack.c          | 21 +++++++--------------
 arch/mips/src/common/mips_createstack.c       |  3 ++-
 arch/mips/src/common/mips_releasestack.c      | 21 +++++++--------------
 arch/mips/src/common/mips_usestack.c          |  2 +-
 arch/misoc/src/lm32/lm32_createstack.c        |  3 ++-
 arch/misoc/src/lm32/lm32_releasestack.c       | 21 +++++++--------------
 arch/misoc/src/lm32/lm32_usestack.c           |  2 +-
 arch/misoc/src/minerva/minerva_createstack.c  |  3 ++-
 arch/misoc/src/minerva/minerva_releasestack.c | 21 +++++++--------------
 arch/misoc/src/minerva/minerva_usestack.c     |  2 +-
 arch/or1k/src/common/up_createstack.c         |  4 ++--
 arch/or1k/src/common/up_releasestack.c        | 21 +++++++--------------
 arch/or1k/src/common/up_usestack.c            |  2 +-
 arch/renesas/src/common/up_createstack.c      |  3 ++-
 arch/renesas/src/common/up_releasestack.c     | 21 +++++++--------------
 arch/renesas/src/common/up_usestack.c         |  2 +-
 arch/risc-v/src/common/riscv_createstack.c    |  3 ++-
 arch/risc-v/src/common/riscv_releasestack.c   | 21 +++++++--------------
 arch/sim/src/sim/up_createstack.c             |  4 ++--
 arch/sim/src/sim/up_releasestack.c            | 12 +++++-------
 arch/x86/src/i486/up_createstack.c            |  3 ++-
 arch/x86/src/i486/up_releasestack.c           | 21 +++++++--------------
 arch/x86/src/i486/up_usestack.c               |  2 +-
 arch/x86_64/src/intel64/up_createstack.c      |  3 ++-
 arch/x86_64/src/intel64/up_releasestack.c     | 11 +++++------
 arch/x86_64/src/intel64/up_usestack.c         |  2 +-
 arch/xtensa/src/common/xtensa_createstack.c   |  3 ++-
 arch/xtensa/src/common/xtensa_releasestack.c  | 21 +++++++--------------
 arch/xtensa/src/common/xtensa_usestack.c      |  2 +-
 arch/z16/src/common/z16_createstack.c         |  3 ++-
 arch/z16/src/common/z16_releasestack.c        | 16 ++++++----------
 arch/z80/src/common/z80_createstack.c         |  3 ++-
 arch/z80/src/common/z80_releasestack.c        | 21 +++++++--------------
 arch/z80/src/common/z80_usestack.c            |  2 +-
 include/nuttx/sched.h                         |  3 ++-
 44 files changed, 146 insertions(+), 222 deletions(-)

diff --git a/arch/arm/src/common/arm_createstack.c b/arch/arm/src/common/arm_createstack.c
index b14ba88..14da833 100644
--- a/arch/arm/src/common/arm_createstack.c
+++ b/arch/arm/src/common/arm_createstack.c
@@ -197,7 +197,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
        */
 
       tcb->adj_stack_size = stack_size;
-      tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
+      tcb->stack_base_ptr = tcb->stack_alloc_ptr;
 
 #ifdef CONFIG_STACK_COLORATION
       /* If stack debug is enabled, then fill the stack with a
@@ -207,6 +207,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
       arm_stack_color(tcb->stack_base_ptr, tcb->adj_stack_size);
 #endif /* CONFIG_STACK_COLORATION */
+      tcb->flags |= TCB_FLAG_FREE_STACK;
 
       board_autoled_on(LED_STACKCREATED);
       return OK;
diff --git a/arch/arm/src/common/arm_releasestack.c b/arch/arm/src/common/arm_releasestack.c
index 351d2d0..34e0959 100644
--- a/arch/arm/src/common/arm_releasestack.c
+++ b/arch/arm/src/common/arm_releasestack.c
@@ -71,35 +71,28 @@ void up_release_stack(FAR struct tcb_s *dtcb, uint8_t ttype)
 {
   /* Is there a stack allocated? */
 
-  if (dtcb->stack_alloc_ptr)
+  if (dtcb->stack_alloc_ptr && (dtcb->flags & TCB_FLAG_FREE_STACK))
     {
 #ifdef CONFIG_MM_KERNEL_HEAP
       /* Use the kernel allocator if this is a kernel thread */
 
       if (ttype == TCB_FLAG_TTYPE_KERNEL)
         {
-          if (kmm_heapmember(dtcb->stack_alloc_ptr))
-            {
-              kmm_free(dtcb->stack_alloc_ptr);
-            }
+          kmm_free(dtcb->stack_alloc_ptr);
         }
       else
 #endif
         {
           /* Use the user-space allocator if this is a task or pthread */
 
-          if (umm_heapmember(dtcb->stack_alloc_ptr))
-            {
-              kumm_free(dtcb->stack_alloc_ptr);
-            }
+          kumm_free(dtcb->stack_alloc_ptr);
         }
-
-      /* Mark the stack freed */
-
-      dtcb->stack_alloc_ptr = NULL;
     }
 
-  /* The size of the allocated stack is now zero */
+  /* Mark the stack freed */
 
+  dtcb->flags &= ~TCB_FLAG_FREE_STACK;
+  dtcb->stack_alloc_ptr = NULL;
+  dtcb->stack_base_ptr = NULL;
   dtcb->adj_stack_size = 0;
 }
diff --git a/arch/arm/src/common/arm_usestack.c b/arch/arm/src/common/arm_usestack.c
index dcef734..879b36c 100644
--- a/arch/arm/src/common/arm_usestack.c
+++ b/arch/arm/src/common/arm_usestack.c
@@ -117,7 +117,7 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
   /* Save the new stack allocation */
 
   tcb->stack_alloc_ptr = stack;
-  tcb->stack_base_ptr   = tcb->stack_alloc_ptr;
+  tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
   tcb->adj_stack_size  =
       STACK_ALIGN_DOWN((uintptr_t)stack + stack_size) - (uintptr_t)stack;
 
diff --git a/arch/avr/src/avr/up_createstack.c b/arch/avr/src/avr/up_createstack.c
index cbff07b..1f697bf 100644
--- a/arch/avr/src/avr/up_createstack.c
+++ b/arch/avr/src/avr/up_createstack.c
@@ -178,8 +178,9 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
       /* Save the adjusted stack values in the struct tcb_s */
 
-      tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
+      tcb->stack_base_ptr = tcb->stack_alloc_ptr;
       tcb->adj_stack_size = stack_size;
+      tcb->flags |= TCB_FLAG_FREE_STACK;
 
 #if defined(ARCH_HAVE_LEDS)
       board_autoled_on(LED_STACKCREATED);
diff --git a/arch/avr/src/avr/up_usestack.c b/arch/avr/src/avr/up_usestack.c
index e6ec6a3..1ab016b 100644
--- a/arch/avr/src/avr/up_usestack.c
+++ b/arch/avr/src/avr/up_usestack.c
@@ -106,7 +106,7 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
 
   /* Save the adjusted stack values in the struct tcb_s */
 
-  tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
+  tcb->stack_base_ptr = tcb->stack_alloc_ptr;
   tcb->adj_stack_size = stack_size;
 
   return OK;
diff --git a/arch/avr/src/avr32/up_createstack.c b/arch/avr/src/avr32/up_createstack.c
index 4b4cc70..0ab6201 100644
--- a/arch/avr/src/avr32/up_createstack.c
+++ b/arch/avr/src/avr32/up_createstack.c
@@ -201,8 +201,9 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
       /* Save the adjusted stack values in the struct tcb_s */
 
-      tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
+      tcb->stack_base_ptr = tcb->stack_alloc_ptr;
       tcb->adj_stack_size = size_of_stack;
+      tcb->flags |= TCB_FLAG_FREE_STACK;
 
       board_autoled_on(LED_STACKCREATED);
       return OK;
diff --git a/arch/avr/src/avr32/up_usestack.c b/arch/avr/src/avr32/up_usestack.c
index 7ad72a7..e6a1661 100644
--- a/arch/avr/src/avr32/up_usestack.c
+++ b/arch/avr/src/avr32/up_usestack.c
@@ -119,7 +119,7 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
 
   /* Save the adjusted stack values in the struct tcb_s */
 
-  tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
+  tcb->stack_base_ptr = tcb->stack_alloc_ptr;
   tcb->adj_stack_size = size_of_stack;
 
   return OK;
diff --git a/arch/avr/src/common/up_releasestack.c b/arch/avr/src/common/up_releasestack.c
index a44a41a..bd53ac1 100644
--- a/arch/avr/src/common/up_releasestack.c
+++ b/arch/avr/src/common/up_releasestack.c
@@ -79,35 +79,28 @@ void up_release_stack(FAR struct tcb_s *dtcb, uint8_t ttype)
 {
   /* Is there a stack allocated? */
 
-  if (dtcb->stack_alloc_ptr)
+  if (dtcb->stack_alloc_ptr && (dtcb->flags & TCB_FLAG_FREE_STACK))
     {
 #ifdef CONFIG_MM_KERNEL_HEAP
       /* Use the kernel allocator if this is a kernel thread */
 
       if (ttype == TCB_FLAG_TTYPE_KERNEL)
         {
-          if (kmm_heapmember(dtcb->stack_alloc_ptr))
-            {
-              kmm_free(dtcb->stack_alloc_ptr);
-            }
+          kmm_free(dtcb->stack_alloc_ptr);
         }
       else
 #endif
         {
           /* Use the user-space allocator if this is a task or pthread */
 
-          if (umm_heapmember(dtcb->stack_alloc_ptr))
-            {
-              kumm_free(dtcb->stack_alloc_ptr);
-            }
+          kumm_free(dtcb->stack_alloc_ptr);
         }
-
-      /* Mark the stack freed */
-
-      dtcb->stack_alloc_ptr = NULL;
     }
 
-  /* The size of the allocated stack is now zero */
+  /* Mark the stack freed */
 
+  dtcb->flags &= ~TCB_FLAG_FREE_STACK;
+  dtcb->stack_alloc_ptr = NULL;
+  dtcb->stack_base_ptr = NULL;
   dtcb->adj_stack_size = 0;
 }
diff --git a/arch/hc/src/common/up_createstack.c b/arch/hc/src/common/up_createstack.c
index bb928fb..f98dd4a 100644
--- a/arch/hc/src/common/up_createstack.c
+++ b/arch/hc/src/common/up_createstack.c
@@ -200,8 +200,9 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
       /* Save the adjusted stack values in the struct tcb_s */
 
-      tcb->stack_base_ptr  = tcb->alloc_stack_ptr;
+      tcb->stack_base_ptr = tcb->alloc_stack_ptr;
       tcb->adj_stack_size = size_of_stack;
+      tcb->flags |= TCB_FLAG_FREE_STACK;
 
       board_autoled_on(LED_STACKCREATED);
       return OK;
diff --git a/arch/hc/src/common/up_releasestack.c b/arch/hc/src/common/up_releasestack.c
index e7fcb21..c695b0f 100644
--- a/arch/hc/src/common/up_releasestack.c
+++ b/arch/hc/src/common/up_releasestack.c
@@ -79,35 +79,28 @@ void up_release_stack(FAR struct tcb_s *dtcb, uint8_t ttype)
 {
   /* Is there a stack allocated? */
 
-  if (dtcb->stack_alloc_ptr)
+  if (dtcb->stack_alloc_ptr && (dtcb->flags & TCB_FLAG_FREE_STACK))
     {
 #ifdef CONFIG_MM_KERNEL_HEAP
       /* Use the kernel allocator if this is a kernel thread */
 
       if (ttype == TCB_FLAG_TTYPE_KERNEL)
         {
-          if (kmm_heapmember(dtcb->stack_alloc_ptr))
-            {
-              kmm_free(dtcb->stack_alloc_ptr);
-            }
+          kmm_free(dtcb->stack_alloc_ptr);
         }
       else
 #endif
         {
           /* Use the user-space allocator if this is a task or pthread */
 
-          if (umm_heapmember(dtcb->stack_alloc_ptr))
-            {
-              kumm_free(dtcb->stack_alloc_ptr);
-            }
+          kumm_free(dtcb->stack_alloc_ptr);
         }
-
-      /* Mark the stack freed */
-
-      dtcb->stack_alloc_ptr = NULL;
     }
 
-  /* The size of the allocated stack is now zero */
+  /* Mark the stack freed */
 
+  dtcb->flags &= ~TCB_FLAG_FREE_STACK;
+  dtcb->stack_alloc_ptr = NULL;
+  dtcb->stack_base_ptr = NULL;
   dtcb->adj_stack_size = 0;
 }
diff --git a/arch/mips/src/common/mips_createstack.c b/arch/mips/src/common/mips_createstack.c
index 37a1926..b16110f 100644
--- a/arch/mips/src/common/mips_createstack.c
+++ b/arch/mips/src/common/mips_createstack.c
@@ -227,8 +227,9 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
       /* Save the adjusted stack values in the struct tcb_s */
 
-      tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
+      tcb->stack_base_ptr = tcb->stack_alloc_ptr;
       tcb->adj_stack_size = size_of_stack;
+      tcb->flags |= TCB_FLAG_FREE_STACK;
 
       board_autoled_on(LED_STACKCREATED);
       return OK;
diff --git a/arch/mips/src/common/mips_releasestack.c b/arch/mips/src/common/mips_releasestack.c
index 3ca1292..79bfdb3 100644
--- a/arch/mips/src/common/mips_releasestack.c
+++ b/arch/mips/src/common/mips_releasestack.c
@@ -79,35 +79,28 @@ void up_release_stack(FAR struct tcb_s *dtcb, uint8_t ttype)
 {
   /* Is there a stack allocated? */
 
-  if (dtcb->stack_alloc_ptr)
+  if (dtcb->stack_alloc_ptr && (dtcb->flags & TCB_FLAG_FREE_STACK))
     {
 #ifdef CONFIG_MM_KERNEL_HEAP
       /* Use the kernel allocator if this is a kernel thread */
 
       if (ttype == TCB_FLAG_TTYPE_KERNEL)
         {
-          if (kmm_heapmember(dtcb->stack_alloc_ptr))
-            {
-              kmm_free(dtcb->stack_alloc_ptr);
-            }
+          kmm_free(dtcb->stack_alloc_ptr);
         }
       else
 #endif
         {
           /* Use the user-space allocator if this is a task or pthread */
 
-          if (umm_heapmember(dtcb->stack_alloc_ptr))
-            {
-              kumm_free(dtcb->stack_alloc_ptr);
-            }
+          kumm_free(dtcb->stack_alloc_ptr);
         }
-
-      /* Mark the stack freed */
-
-      dtcb->stack_alloc_ptr = NULL;
     }
 
-  /* The size of the allocated stack is now zero */
+  /* Mark the stack freed */
 
+  dtcb->flags &= ~TCB_FLAG_FREE_STACK;
+  dtcb->stack_alloc_ptr = NULL;
+  dtcb->stack_base_ptr = NULL;
   dtcb->adj_stack_size = 0;
 }
diff --git a/arch/mips/src/common/mips_usestack.c b/arch/mips/src/common/mips_usestack.c
index 3b9c21b..a2223b6 100644
--- a/arch/mips/src/common/mips_usestack.c
+++ b/arch/mips/src/common/mips_usestack.c
@@ -145,7 +145,7 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
 
   /* Save the adjusted stack values in the struct tcb_s */
 
-  tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
+  tcb->stack_base_ptr = tcb->stack_alloc_ptr;
   tcb->adj_stack_size = size_of_stack;
 
   return OK;
diff --git a/arch/misoc/src/lm32/lm32_createstack.c b/arch/misoc/src/lm32/lm32_createstack.c
index 15d9c52..87cdbcc 100644
--- a/arch/misoc/src/lm32/lm32_createstack.c
+++ b/arch/misoc/src/lm32/lm32_createstack.c
@@ -219,8 +219,9 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
       /* Save the adjusted stack values in the struct tcb_s */
 
-      tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
+      tcb->stack_base_ptr = tcb->stack_alloc_ptr;
       tcb->adj_stack_size = size_of_stack;
+      tcb->flags |= TCB_FLAG_FREE_STACK;
 
       board_autoled_on(LED_STACKCREATED);
       return OK;
diff --git a/arch/misoc/src/lm32/lm32_releasestack.c b/arch/misoc/src/lm32/lm32_releasestack.c
index 86fe476..64af00e 100644
--- a/arch/misoc/src/lm32/lm32_releasestack.c
+++ b/arch/misoc/src/lm32/lm32_releasestack.c
@@ -71,35 +71,28 @@ void up_release_stack(FAR struct tcb_s *dtcb, uint8_t ttype)
 {
   /* Is there a stack allocated? */
 
-  if (dtcb->stack_alloc_ptr)
+  if (dtcb->stack_alloc_ptr && (dtcb->flags & TCB_FLAG_FREE_STACK))
     {
 #ifdef CONFIG_MM_KERNEL_HEAP
       /* Use the kernel allocator if this is a kernel thread */
 
       if (ttype == TCB_FLAG_TTYPE_KERNEL)
         {
-          if (kmm_heapmember(dtcb->stack_alloc_ptr))
-            {
-              kmm_free(dtcb->stack_alloc_ptr);
-            }
+          kmm_free(dtcb->stack_alloc_ptr);
         }
       else
 #endif
         {
           /* Use the user-space allocator if this is a task or pthread */
 
-          if (umm_heapmember(dtcb->stack_alloc_ptr))
-            {
-              kumm_free(dtcb->stack_alloc_ptr);
-            }
+          kumm_free(dtcb->stack_alloc_ptr);
         }
-
-      /* Mark the stack freed */
-
-      dtcb->stack_alloc_ptr = NULL;
     }
 
-  /* The size of the allocated stack is now zero */
+  /* Mark the stack freed */
 
+  dtcb->flags &= ~TCB_FLAG_FREE_STACK;
+  dtcb->stack_alloc_ptr = NULL;
+  dtcb->stack_base_ptr = NULL;
   dtcb->adj_stack_size = 0;
 }
diff --git a/arch/misoc/src/lm32/lm32_usestack.c b/arch/misoc/src/lm32/lm32_usestack.c
index 902fe67..ffc13c9 100644
--- a/arch/misoc/src/lm32/lm32_usestack.c
+++ b/arch/misoc/src/lm32/lm32_usestack.c
@@ -115,7 +115,7 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
 
   /* Save the adjusted stack values in the struct tcb_s */
 
-  tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
+  tcb->stack_base_ptr = tcb->stack_alloc_ptr;
   tcb->adj_stack_size = size_of_stack;
 
   return OK;
diff --git a/arch/misoc/src/minerva/minerva_createstack.c b/arch/misoc/src/minerva/minerva_createstack.c
index 754c47d..1168eb1 100644
--- a/arch/misoc/src/minerva/minerva_createstack.c
+++ b/arch/misoc/src/minerva/minerva_createstack.c
@@ -212,8 +212,9 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
       /* Save the adjusted stack values in the struct tcb_s */
 
-      tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
+      tcb->stack_base_ptr = tcb->stack_alloc_ptr;
       tcb->adj_stack_size = size_of_stack;
+      tcb->flags |= TCB_FLAG_FREE_STACK;
 
       board_autoled_on(LED_STACKCREATED);
       return OK;
diff --git a/arch/misoc/src/minerva/minerva_releasestack.c b/arch/misoc/src/minerva/minerva_releasestack.c
index cc1978d..d43f76e 100644
--- a/arch/misoc/src/minerva/minerva_releasestack.c
+++ b/arch/misoc/src/minerva/minerva_releasestack.c
@@ -71,35 +71,28 @@ void up_release_stack(FAR struct tcb_s *dtcb, uint8_t ttype)
 {
   /* Is there a stack allocated? */
 
-  if (dtcb->stack_alloc_ptr)
+  if (dtcb->stack_alloc_ptr && (dtcb->flags & TCB_FLAG_FREE_STACK))
     {
 #ifdef CONFIG_MM_KERNEL_HEAP
       /* Use the kernel allocator if this is a kernel thread */
 
       if (ttype == TCB_FLAG_TTYPE_KERNEL)
         {
-          if (kmm_heapmember(dtcb->stack_alloc_ptr))
-            {
-              kmm_free(dtcb->stack_alloc_ptr);
-            }
+          kmm_free(dtcb->stack_alloc_ptr);
         }
       else
 #endif
         {
           /* Use the user-space allocator if this is a task or pthread */
 
-          if (umm_heapmember(dtcb->stack_alloc_ptr))
-            {
-              kumm_free(dtcb->stack_alloc_ptr);
-            }
+          kumm_free(dtcb->stack_alloc_ptr);
         }
-
-      /* Mark the stack freed */
-
-      dtcb->stack_alloc_ptr = NULL;
     }
 
-  /* The size of the allocated stack is now zero */
+  /* Mark the stack freed */
 
+  dtcb->flags &= ~TCB_FLAG_FREE_STACK;
+  dtcb->stack_alloc_ptr = NULL;
+  dtcb->stack_base_ptr = NULL;
   dtcb->adj_stack_size = 0;
 }
diff --git a/arch/misoc/src/minerva/minerva_usestack.c b/arch/misoc/src/minerva/minerva_usestack.c
index 7f84448..6f30647 100644
--- a/arch/misoc/src/minerva/minerva_usestack.c
+++ b/arch/misoc/src/minerva/minerva_usestack.c
@@ -115,7 +115,7 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
 
   /* Save the adjusted stack values in the struct tcb_s */
 
-  tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
+  tcb->stack_base_ptr = tcb->stack_alloc_ptr;
   tcb->adj_stack_size = size_of_stack;
 
   return OK;
diff --git a/arch/or1k/src/common/up_createstack.c b/arch/or1k/src/common/up_createstack.c
index 8a92134..404a29a 100644
--- a/arch/or1k/src/common/up_createstack.c
+++ b/arch/or1k/src/common/up_createstack.c
@@ -191,7 +191,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
       /* Save the adjusted stack values in the struct tcb_s */
 
-      tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
+      tcb->stack_base_ptr = tcb->stack_alloc_ptr;
       tcb->adj_stack_size = size_of_stack;
 
 #ifdef CONFIG_STACK_COLORATION
@@ -201,8 +201,8 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
        */
 
       up_stack_color(tcb->stack_base_ptr, tcb->adj_stack_size);
-
 #endif /* CONFIG_STACK_COLORATION */
+      tcb->flags |= TCB_FLAG_FREE_STACK;
 
       board_autoled_on(LED_STACKCREATED);
       return OK;
diff --git a/arch/or1k/src/common/up_releasestack.c b/arch/or1k/src/common/up_releasestack.c
index 1aba6dd..ba85410 100644
--- a/arch/or1k/src/common/up_releasestack.c
+++ b/arch/or1k/src/common/up_releasestack.c
@@ -75,35 +75,28 @@ void up_release_stack(FAR struct tcb_s *dtcb, uint8_t ttype)
 {
   /* Is there a stack allocated? */
 
-  if (dtcb->stack_alloc_ptr)
+  if (dtcb->stack_alloc_ptr && (dtcb->flags & TCB_FLAG_FREE_STACK))
     {
 #ifdef CONFIG_MM_KERNEL_HEAP
       /* Use the kernel allocator if this is a kernel thread */
 
       if (ttype == TCB_FLAG_TTYPE_KERNEL)
         {
-          if (kmm_heapmember(dtcb->stack_alloc_ptr))
-            {
-              kmm_free(dtcb->stack_alloc_ptr);
-            }
+          kmm_free(dtcb->stack_alloc_ptr);
         }
       else
 #endif
         {
           /* Use the user-space allocator if this is a task or pthread */
 
-          if (umm_heapmember(dtcb->stack_alloc_ptr))
-            {
-              kumm_free(dtcb->stack_alloc_ptr);
-            }
+          kumm_free(dtcb->stack_alloc_ptr);
         }
-
-      /* Mark the stack freed */
-
-      dtcb->stack_alloc_ptr = NULL;
     }
 
-  /* The size of the allocated stack is now zero */
+  /* Mark the stack freed */
 
+  dtcb->flags &= ~TCB_FLAG_FREE_STACK;
+  dtcb->stack_alloc_ptr = NULL;
+  dtcb->stack_base_ptr = NULL;
   dtcb->adj_stack_size = 0;
 }
diff --git a/arch/or1k/src/common/up_usestack.c b/arch/or1k/src/common/up_usestack.c
index 856fc45..e2740db 100644
--- a/arch/or1k/src/common/up_usestack.c
+++ b/arch/or1k/src/common/up_usestack.c
@@ -115,7 +115,7 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
 
   /* Save the adjusted stack values in the struct tcb_s */
 
-  tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
+  tcb->stack_base_ptr = tcb->stack_alloc_ptr;
   tcb->adj_stack_size = size_of_stack;
 
   return OK;
diff --git a/arch/renesas/src/common/up_createstack.c b/arch/renesas/src/common/up_createstack.c
index 173c6fa..673a192 100644
--- a/arch/renesas/src/common/up_createstack.c
+++ b/arch/renesas/src/common/up_createstack.c
@@ -200,8 +200,9 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
       /* Save the adjusted stack values in the struct tcb_s */
 
-      tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
+      tcb->stack_base_ptr = tcb->stack_alloc_ptr;
       tcb->adj_stack_size = size_of_stack;
+      tcb->flags |= TCB_FLAG_FREE_STACK;
 
       board_autoled_on(LED_STACKCREATED);
       return OK;
diff --git a/arch/renesas/src/common/up_releasestack.c b/arch/renesas/src/common/up_releasestack.c
index 77ac43e..0d440d4 100644
--- a/arch/renesas/src/common/up_releasestack.c
+++ b/arch/renesas/src/common/up_releasestack.c
@@ -79,35 +79,28 @@ void up_release_stack(FAR struct tcb_s *dtcb, uint8_t ttype)
 {
   /* Is there a stack allocated? */
 
-  if (dtcb->stack_alloc_ptr)
+  if (dtcb->stack_alloc_ptr && (dtcb->flags & TCB_FLAG_FREE_STACK))
     {
 #ifdef CONFIG_MM_KERNEL_HEAP
       /* Use the kernel allocator if this is a kernel thread */
 
       if (ttype == TCB_FLAG_TTYPE_KERNEL)
         {
-          if (kmm_heapmember(dtcb->stack_alloc_ptr))
-            {
-              kmm_free(dtcb->stack_alloc_ptr);
-            }
+          kmm_free(dtcb->stack_alloc_ptr);
         }
       else
 #endif
         {
           /* Use the user-space allocator if this is a task or pthread */
 
-          if (umm_heapmember(dtcb->stack_alloc_ptr))
-            {
-              kumm_free(dtcb->stack_alloc_ptr);
-            }
+          kumm_free(dtcb->stack_alloc_ptr);
         }
-
-      /* Mark the stack freed */
-
-      dtcb->stack_alloc_ptr = NULL;
     }
 
-  /* The size of the allocated stack is now zero */
+  /* Mark the stack freed */
 
+  dtcb->flags &= ~TCB_FLAG_FREE_STACK;
+  dtcb->stack_alloc_ptr = NULL;
+  dtcb->stack_base_ptr = NULL;
   dtcb->adj_stack_size = 0;
 }
diff --git a/arch/renesas/src/common/up_usestack.c b/arch/renesas/src/common/up_usestack.c
index 7546f77..db2987a 100644
--- a/arch/renesas/src/common/up_usestack.c
+++ b/arch/renesas/src/common/up_usestack.c
@@ -117,7 +117,7 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
 
   /* Save the adjusted stack values in the struct tcb_s */
 
-  tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
+  tcb->stack_base_ptr = tcb->stack_alloc_ptr;
   tcb->adj_stack_size = size_of_stack;
 
   return OK;
diff --git a/arch/risc-v/src/common/riscv_createstack.c b/arch/risc-v/src/common/riscv_createstack.c
index 51e5787..1616c99 100644
--- a/arch/risc-v/src/common/riscv_createstack.c
+++ b/arch/risc-v/src/common/riscv_createstack.c
@@ -204,7 +204,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
       /* Save the adjusted stack values in the struct tcb_s */
 
-      tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
+      tcb->stack_base_ptr = tcb->stack_alloc_ptr;
       tcb->adj_stack_size = size_of_stack;
 
 #ifdef CONFIG_STACK_COLORATION
@@ -216,6 +216,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
       riscv_stack_color(tcb->stack_base_ptr, tcb->adj_stack_size);
 
 #endif /* CONFIG_STACK_COLORATION */
+      tcb->flags |= TCB_FLAG_FREE_STACK;
 
       board_autoled_on(LED_STACKCREATED);
       return OK;
diff --git a/arch/risc-v/src/common/riscv_releasestack.c b/arch/risc-v/src/common/riscv_releasestack.c
index d681c42..a50f5db 100644
--- a/arch/risc-v/src/common/riscv_releasestack.c
+++ b/arch/risc-v/src/common/riscv_releasestack.c
@@ -79,35 +79,28 @@ void up_release_stack(FAR struct tcb_s *dtcb, uint8_t ttype)
 {
   /* Is there a stack allocated? */
 
-  if (dtcb->stack_alloc_ptr)
+  if (dtcb->stack_alloc_ptr && (dtcb->flags & TCB_FLAG_FREE_STACK))
     {
 #ifdef CONFIG_MM_KERNEL_HEAP
       /* Use the kernel allocator if this is a kernel thread */
 
       if (ttype == TCB_FLAG_TTYPE_KERNEL)
         {
-          if (kmm_heapmember(dtcb->stack_alloc_ptr))
-            {
-              kmm_free(dtcb->stack_alloc_ptr);
-            }
+          kmm_free(dtcb->stack_alloc_ptr);
         }
       else
 #endif
         {
           /* Use the user-space allocator if this is a task or pthread */
 
-          if (umm_heapmember(dtcb->stack_alloc_ptr))
-            {
-              kumm_free(dtcb->stack_alloc_ptr);
-            }
+          kumm_free(dtcb->stack_alloc_ptr);
         }
-
-      /* Mark the stack freed */
-
-      dtcb->stack_alloc_ptr = NULL;
     }
 
-  /* The size of the allocated stack is now zero */
+  /* Mark the stack freed */
 
+  dtcb->flags &= ~TCB_FLAG_FREE_STACK;
+  dtcb->stack_alloc_ptr = NULL;
+  dtcb->stack_base_ptr = NULL;
   dtcb->adj_stack_size = 0;
 }
diff --git a/arch/sim/src/sim/up_createstack.c b/arch/sim/src/sim/up_createstack.c
index b5f4ad6..ebe36e2 100644
--- a/arch/sim/src/sim/up_createstack.c
+++ b/arch/sim/src/sim/up_createstack.c
@@ -124,7 +124,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
       tcb->adj_stack_size  = adj_stack_size;
       tcb->stack_alloc_ptr = stack_alloc_ptr;
-      tcb->stack_base_ptr   = tcb->stack_alloc_ptr;
+      tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
 
 #ifdef CONFIG_STACK_COLORATION
       /* If stack debug is enabled, then fill the stack with a
@@ -133,8 +133,8 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
        */
 
       up_stack_color(tcb->stack_base_ptr, tcb->adj_stack_size);
-
 #endif /* CONFIG_STACK_COLORATION */
+      tcb->flags |= TCB_FLAG_FREE_STACK;
 
       ret = OK;
     }
diff --git a/arch/sim/src/sim/up_releasestack.c b/arch/sim/src/sim/up_releasestack.c
index 179b699..1210e39 100644
--- a/arch/sim/src/sim/up_releasestack.c
+++ b/arch/sim/src/sim/up_releasestack.c
@@ -62,17 +62,15 @@ void up_release_stack(FAR struct tcb_s *dtcb, uint8_t ttype)
 {
   /* Is there a stack allocated? */
 
-  if (dtcb->stack_alloc_ptr)
+  if (dtcb->stack_alloc_ptr && (dtcb->flags & TCB_FLAG_FREE_STACK))
     {
-      if (umm_heapmember(dtcb->stack_alloc_ptr))
-        {
-          kumm_free(dtcb->stack_alloc_ptr);
-        }
+      kumm_free(dtcb->stack_alloc_ptr);
     }
 
   /* Mark the stack freed */
 
+  dtcb->flags &= ~TCB_FLAG_FREE_STACK;
   dtcb->stack_alloc_ptr = NULL;
-  dtcb->adj_stack_size  = 0;
-  dtcb->stack_base_ptr   = NULL;
+  dtcb->stack_base_ptr = NULL;
+  dtcb->adj_stack_size = 0;
 }
diff --git a/arch/x86/src/i486/up_createstack.c b/arch/x86/src/i486/up_createstack.c
index 7f65fab..c4f724f 100644
--- a/arch/x86/src/i486/up_createstack.c
+++ b/arch/x86/src/i486/up_createstack.c
@@ -200,8 +200,9 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
       /* Save the adjusted stack values in the struct tcb_s */
 
-      tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
+      tcb->stack_base_ptr = tcb->stack_alloc_ptr;
       tcb->adj_stack_size = size_of_stack;
+      tcb->flags |= TCB_FLAG_FREE_STACK;
 
       board_autoled_on(LED_STACKCREATED);
       return OK;
diff --git a/arch/x86/src/i486/up_releasestack.c b/arch/x86/src/i486/up_releasestack.c
index 2e54e9f..9122ae6 100644
--- a/arch/x86/src/i486/up_releasestack.c
+++ b/arch/x86/src/i486/up_releasestack.c
@@ -79,35 +79,28 @@ void up_release_stack(FAR struct tcb_s *dtcb, uint8_t ttype)
 {
   /* Is there a stack allocated? */
 
-  if (dtcb->stack_alloc_ptr)
+  if (dtcb->stack_alloc_ptr && (dtcb->flags & TCB_FLAG_FREE_STACK))
     {
 #ifdef CONFIG_MM_KERNEL_HEAP
       /* Use the kernel allocator if this is a kernel thread */
 
       if (ttype == TCB_FLAG_TTYPE_KERNEL)
         {
-          if (kmm_heapmember(dtcb->stack_alloc_ptr))
-            {
-              kmm_free(dtcb->stack_alloc_ptr);
-            }
+          kmm_free(dtcb->stack_alloc_ptr);
         }
       else
 #endif
         {
           /* Use the user-space allocator if this is a task or pthread */
 
-          if (umm_heapmember(dtcb->stack_alloc_ptr))
-            {
-              kumm_free(dtcb->stack_alloc_ptr);
-            }
+          kumm_free(dtcb->stack_alloc_ptr);
         }
-
-      /* Mark the stack freed */
-
-      dtcb->stack_alloc_ptr = NULL;
     }
 
-  /* The size of the allocated stack is now zero */
+  /* Mark the stack freed */
 
+  dtcb->flags &= ~TCB_FLAG_FREE_STACK;
+  dtcb->stack_alloc_ptr = NULL;
+  dtcb->stack_base_ptr = NULL;
   dtcb->adj_stack_size = 0;
 }
diff --git a/arch/x86/src/i486/up_usestack.c b/arch/x86/src/i486/up_usestack.c
index 11d4e20..221c5e2 100644
--- a/arch/x86/src/i486/up_usestack.c
+++ b/arch/x86/src/i486/up_usestack.c
@@ -117,7 +117,7 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
 
   /* Save the adjusted stack values in the struct tcb_s */
 
-  tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
+  tcb->stack_base_ptr = tcb->stack_alloc_ptr;
   tcb->adj_stack_size = size_of_stack;
 
   return OK;
diff --git a/arch/x86_64/src/intel64/up_createstack.c b/arch/x86_64/src/intel64/up_createstack.c
index 8f1658f..de1c663 100644
--- a/arch/x86_64/src/intel64/up_createstack.c
+++ b/arch/x86_64/src/intel64/up_createstack.c
@@ -202,8 +202,9 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
       /* Save the adjusted stack values in the struct tcb_s */
 
-      tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
+      tcb->stack_base_ptr = tcb->stack_alloc_ptr;
       tcb->adj_stack_size = size_of_stack;
+      tcb->flags |= TCB_FLAG_FREE_STACK;
 
       board_autoled_on(LED_STACKCREATED);
       return OK;
diff --git a/arch/x86_64/src/intel64/up_releasestack.c b/arch/x86_64/src/intel64/up_releasestack.c
index eefe130..e14f948 100644
--- a/arch/x86_64/src/intel64/up_releasestack.c
+++ b/arch/x86_64/src/intel64/up_releasestack.c
@@ -81,7 +81,7 @@ void up_release_stack(FAR struct tcb_s *dtcb, uint8_t ttype)
 {
   /* Is there a stack allocated? */
 
-  if (dtcb->stack_alloc_ptr)
+  if (dtcb->stack_alloc_ptr && (dtcb->flags & TCB_FLAG_FREE_STACK))
     {
 #ifdef CONFIG_MM_KERNEL_HEAP
       /* Use the kernel allocator if this is a kernel thread */
@@ -97,13 +97,12 @@ void up_release_stack(FAR struct tcb_s *dtcb, uint8_t ttype)
 
           kumm_free(dtcb->stack_alloc_ptr);
         }
-
-      /* Mark the stack freed */
-
-      dtcb->stack_alloc_ptr = NULL;
     }
 
-  /* The size of the allocated stack is now zero */
+  /* Mark the stack freed */
 
+  dtcb->flags &= ~TCB_FLAG_FREE_STACK;
+  dtcb->stack_alloc_ptr = NULL;
+  dtcb->stack_base_ptr = NULL;
   dtcb->adj_stack_size = 0;
 }
diff --git a/arch/x86_64/src/intel64/up_usestack.c b/arch/x86_64/src/intel64/up_usestack.c
index 219badd..0f1bb4d 100644
--- a/arch/x86_64/src/intel64/up_usestack.c
+++ b/arch/x86_64/src/intel64/up_usestack.c
@@ -119,7 +119,7 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
 
   /* Save the adjusted stack values in the struct tcb_s */
 
-  tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
+  tcb->stack_base_ptr = tcb->stack_alloc_ptr;
   tcb->adj_stack_size = size_of_stack;
 
   return OK;
diff --git a/arch/xtensa/src/common/xtensa_createstack.c b/arch/xtensa/src/common/xtensa_createstack.c
index 95dd462..ef7a546 100644
--- a/arch/xtensa/src/common/xtensa_createstack.c
+++ b/arch/xtensa/src/common/xtensa_createstack.c
@@ -242,7 +242,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
       /* Save the adjusted stack values in the struct tcb_s */
 
-      tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
+      tcb->stack_base_ptr = tcb->stack_alloc_ptr;
       tcb->adj_stack_size = size_of_stack;
 
 #ifdef CONFIG_STACK_COLORATION
@@ -253,6 +253,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
       up_stack_color(tcb->stack_base_ptr, tcb->adj_stack_size);
 #endif
+      tcb->flags |= TCB_FLAG_FREE_STACK;
 
       board_autoled_on(LED_STACKCREATED);
       return OK;
diff --git a/arch/xtensa/src/common/xtensa_releasestack.c b/arch/xtensa/src/common/xtensa_releasestack.c
index 3130d15..0ef7f19 100644
--- a/arch/xtensa/src/common/xtensa_releasestack.c
+++ b/arch/xtensa/src/common/xtensa_releasestack.c
@@ -72,35 +72,28 @@ void up_release_stack(FAR struct tcb_s *dtcb, uint8_t ttype)
 {
   /* Is there a stack allocated? */
 
-  if (dtcb->stack_alloc_ptr)
+  if (dtcb->stack_alloc_ptr && (dtcb->flags & TCB_FLAG_FREE_STACK))
     {
 #ifdef CONFIG_MM_KERNEL_HEAP
       /* Use the kernel allocator if this is a kernel thread */
 
       if (ttype == TCB_FLAG_TTYPE_KERNEL)
         {
-          if (kmm_heapmember(dtcb->stack_alloc_ptr))
-            {
-              kmm_free(dtcb->stack_alloc_ptr);
-            }
+          kmm_free(dtcb->stack_alloc_ptr);
         }
       else
 #endif
         {
           /* Use the user-space allocator if this is a task or pthread */
 
-          if (UMM_HEAPMEMEBER(dtcb->stack_alloc_ptr))
-            {
-              UMM_FREE(dtcb->stack_alloc_ptr);
-            }
+          UMM_FREE(dtcb->stack_alloc_ptr);
         }
-
-      /* Mark the stack freed */
-
-      dtcb->stack_alloc_ptr = NULL;
     }
 
-  /* The size of the allocated stack is now zero */
+  /* Mark the stack freed */
 
+  dtcb->flags &= ~TCB_FLAG_FREE_STACK;
+  dtcb->stack_alloc_ptr = NULL;
+  dtcb->stack_base_ptr = NULL;
   dtcb->adj_stack_size = 0;
 }
diff --git a/arch/xtensa/src/common/xtensa_usestack.c b/arch/xtensa/src/common/xtensa_usestack.c
index 9f991c6..84657a9 100644
--- a/arch/xtensa/src/common/xtensa_usestack.c
+++ b/arch/xtensa/src/common/xtensa_usestack.c
@@ -123,7 +123,7 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
 
   /* Save the adjusted stack values in the struct tcb_s */
 
-  tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
+  tcb->stack_base_ptr = tcb->stack_alloc_ptr;
   tcb->adj_stack_size = size_of_stack;
 
 #if defined(CONFIG_STACK_COLORATION)
diff --git a/arch/z16/src/common/z16_createstack.c b/arch/z16/src/common/z16_createstack.c
index fee1695..2810dda 100644
--- a/arch/z16/src/common/z16_createstack.c
+++ b/arch/z16/src/common/z16_createstack.c
@@ -194,8 +194,9 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
       /* Save the adjusted stack values in the struct tcb_s */
 
-      tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
+      tcb->stack_base_ptr = tcb->stack_alloc_ptr;
       tcb->adj_stack_size = size_of_stack;
+      tcb->flags |= TCB_FLAG_FREE_STACK;
 
       board_autoled_on(LED_STACKCREATED);
       return OK;
diff --git a/arch/z16/src/common/z16_releasestack.c b/arch/z16/src/common/z16_releasestack.c
index 95f5e95..30810aa 100644
--- a/arch/z16/src/common/z16_releasestack.c
+++ b/arch/z16/src/common/z16_releasestack.c
@@ -73,19 +73,15 @@ void up_release_stack(FAR struct tcb_s *dtcb, uint8_t ttype)
 {
   /* Is there a stack allocated? */
 
-  if (dtcb->stack_alloc_ptr)
+  if (dtcb->stack_alloc_ptr && (dtcb->flags & TCB_FLAG_FREE_STACK))
     {
-      if (umm_heapmember(dtcb->stack_alloc_ptr))
-        {
-          kumm_free(dtcb->stack_alloc_ptr);
-        }
-
-      /* Mark the stack freed */
-
-      dtcb->stack_alloc_ptr = NULL;
+      kumm_free(dtcb->stack_alloc_ptr);
     }
 
-  /* The size of the allocated stack is now zero */
+  /* Mark the stack freed */
 
+  dtcb->flags &= ~TCB_FLAG_FREE_STACK;
+  dtcb->stack_alloc_ptr = NULL;
+  dtcb->stack_base_ptr = NULL;
   dtcb->adj_stack_size = 0;
 }
diff --git a/arch/z80/src/common/z80_createstack.c b/arch/z80/src/common/z80_createstack.c
index 2adc483..5ba5923 100644
--- a/arch/z80/src/common/z80_createstack.c
+++ b/arch/z80/src/common/z80_createstack.c
@@ -199,8 +199,9 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
       /* Save the adjusted stack values in the struct tcb_s */
 
-      tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
+      tcb->stack_base_ptr = tcb->stack_alloc_ptr;
       tcb->adj_stack_size = size_of_stack;
+      tcb->flags |= TCB_FLAG_FREE_STACK;
 
       board_autoled_on(LED_STACKCREATED);
       return OK;
diff --git a/arch/z80/src/common/z80_releasestack.c b/arch/z80/src/common/z80_releasestack.c
index a94b0b1..b5725c2 100644
--- a/arch/z80/src/common/z80_releasestack.c
+++ b/arch/z80/src/common/z80_releasestack.c
@@ -79,35 +79,28 @@ void up_release_stack(FAR struct tcb_s *dtcb, uint8_t ttype)
 {
   /* Is there a stack allocated? */
 
-  if (dtcb->stack_alloc_ptr)
+  if (dtcb->stack_alloc_ptr && (dtcb->flags & TCB_FLAG_FREE_STACK))
     {
 #ifdef CONFIG_MM_KERNEL_HEAP
       /* Use the kernel allocator if this is a kernel thread */
 
       if (ttype == TCB_FLAG_TTYPE_KERNEL)
         {
-          if (kmm_heapmember(dtcb->stack_alloc_ptr))
-            {
-              kmm_free(dtcb->stack_alloc_ptr);
-            }
+          kmm_free(dtcb->stack_alloc_ptr);
         }
       else
 #endif
         {
           /* Use the user-space allocator if this is a task or pthread */
 
-          if (umm_heapmember(dtcb->stack_alloc_ptr))
-            {
-              kumm_free(dtcb->stack_alloc_ptr);
-            }
+          kumm_free(dtcb->stack_alloc_ptr);
         }
-
-      /* Mark the stack freed */
-
-      dtcb->stack_alloc_ptr = NULL;
     }
 
-  /* The size of the allocated stack is now zero */
+  /* Mark the stack freed */
 
+  dtcb->flags &= ~TCB_FLAG_FREE_STACK;
+  dtcb->stack_alloc_ptr = NULL;
+  dtcb->stack_base_ptr = NULL;
   dtcb->adj_stack_size = 0;
 }
diff --git a/arch/z80/src/common/z80_usestack.c b/arch/z80/src/common/z80_usestack.c
index f25211d..c11d4dd 100644
--- a/arch/z80/src/common/z80_usestack.c
+++ b/arch/z80/src/common/z80_usestack.c
@@ -116,7 +116,7 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
 
   /* Save the adjusted stack values in the struct tcb_s */
 
-  tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
+  tcb->stack_base_ptr = tcb->stack_alloc_ptr;
   tcb->adj_stack_size = size_of_stack;
 
   return OK;
diff --git a/include/nuttx/sched.h b/include/nuttx/sched.h
index 8f32440..d54e04f 100644
--- a/include/nuttx/sched.h
+++ b/include/nuttx/sched.h
@@ -107,7 +107,8 @@
 #define TCB_FLAG_SIGNAL_ACTION     (1 << 9)                      /* Bit 8: In a signal handler */
 #define TCB_FLAG_SYSCALL           (1 << 10)                     /* Bit 9: In a system call */
 #define TCB_FLAG_EXIT_PROCESSING   (1 << 11)                     /* Bit 10: Exitting */
-                                                                 /* Bits 11-15: Available */
+#define TCB_FLAG_FREE_STACK        (1 << 12)                     /* Bit 12: Free stack after exit */
+                                                                 /* Bits 13-15: Available */
 
 /* Values for struct task_group tg_flags */