RTX5: Add de-allocation of Arm C library thread data (libspace) when thread is terminated
diff --git a/ARM.CMSIS.pdsc b/ARM.CMSIS.pdsc
index 5511c3e..32e3a82 100644
--- a/ARM.CMSIS.pdsc
+++ b/ARM.CMSIS.pdsc
@@ -14,6 +14,8 @@
        - Added new compiler macros.
       CMSIS-DSP: Moved into separate pack!
       CMSIS-NN: Moved into separate pack!
+      CMSIS-RTOS2: 2.1.3 (unchanged)
+        - RTX 5.5.5 (see revision history for details)
       CMSIS-DAP: 2.1.2 (see revision history for details)
        - Fix DAP_Transfer handling when transfer fails
     </release>
@@ -2314,7 +2316,7 @@
     </component>
 
     <!-- CMSIS-RTOS Keil RTX5 component -->
-    <component Cclass="CMSIS" Cgroup="RTOS" Csub="Keil RTX5" Cversion="5.5.4" Capiversion="1.0.0" condition="RTOS RTX5">
+    <component Cclass="CMSIS" Cgroup="RTOS" Csub="Keil RTX5" Cversion="5.5.5" Capiversion="1.0.0" condition="RTOS RTX5">
       <description>CMSIS-RTOS RTX5 implementation for Cortex-M, SC000, and SC300</description>
       <RTE_Components_h>
         <!-- the following content goes into file 'RTE_Components.h' -->
@@ -2330,7 +2332,7 @@
     </component>
 
     <!-- CMSIS-RTOS2 Keil RTX5 component -->
-    <component Cclass="CMSIS" Cgroup="RTOS2" Csub="Keil RTX5" Cvariant="Library" Cversion="5.5.4" Capiversion="2.1.3" condition="RTOS2 RTX5">
+    <component Cclass="CMSIS" Cgroup="RTOS2" Csub="Keil RTX5" Cvariant="Library" Cversion="5.5.5" Capiversion="2.1.3" condition="RTOS2 RTX5">
       <description>CMSIS-RTOS2 RTX5 for Cortex-M, SC000, SC300, ARMv8-M, ARMv8.1-M (Library)</description>
       <RTE_Components_h>
         <!-- the following content goes into file 'RTE_Components.h' -->
@@ -2389,7 +2391,7 @@
         <file category="library" condition="IARCC ARMv81-MML FP LE"   name="CMSIS/RTOS2/RTX/Library/IAR/RTX_V81MMF.a"   src="CMSIS/RTOS2/RTX/Source"/>
       </files>
     </component>
-    <component Cclass="CMSIS" Cgroup="RTOS2" Csub="Keil RTX5" Cvariant="Library_NS" Cversion="5.5.4" Capiversion="2.1.3" condition="RTOS2 RTX5 NS">
+    <component Cclass="CMSIS" Cgroup="RTOS2" Csub="Keil RTX5" Cvariant="Library_NS" Cversion="5.5.5" Capiversion="2.1.3" condition="RTOS2 RTX5 NS">
       <description>CMSIS-RTOS2 RTX5 for Armv8-M/Armv8.1-M Non-Secure Domain (Library)</description>
       <RTE_Components_h>
         <!-- the following content goes into file 'RTE_Components.h' -->
@@ -2440,7 +2442,7 @@
         <file category="library" condition="IARCC ARMv81-MML FP LE"   name="CMSIS/RTOS2/RTX/Library/IAR/RTX_V81MMFN.a"   src="CMSIS/RTOS2/RTX/Source"/>
       </files>
     </component>
-    <component Cclass="CMSIS" Cgroup="RTOS2" Csub="Keil RTX5" Cvariant="Source" Cversion="5.5.4" Capiversion="2.1.3" condition="RTOS2 RTX5">
+    <component Cclass="CMSIS" Cgroup="RTOS2" Csub="Keil RTX5" Cvariant="Source" Cversion="5.5.5" Capiversion="2.1.3" condition="RTOS2 RTX5">
       <description>CMSIS-RTOS2 RTX5 for Cortex-M, SC000, SC300, ARMv8-M, ARMv8.1-M (Source)</description>
       <RTE_Components_h>
         <!-- the following content goes into file 'RTE_Components.h' -->
@@ -2503,7 +2505,7 @@
         <file category="source" name="CMSIS/RTOS2/Source/os_systick.c"/>
       </files>
     </component>
-    <component Cclass="CMSIS" Cgroup="RTOS2" Csub="Keil RTX5" Cvariant="Source" Cversion="5.5.4" Capiversion="2.1.3" condition="RTOS2 RTX5 v7-A">
+    <component Cclass="CMSIS" Cgroup="RTOS2" Csub="Keil RTX5" Cvariant="Source" Cversion="5.5.5" Capiversion="2.1.3" condition="RTOS2 RTX5 v7-A">
       <description>CMSIS-RTOS2 RTX5 for Armv7-A (Source)</description>
       <RTE_Components_h>
         <!-- the following content goes into file 'RTE_Components.h' -->
@@ -2559,7 +2561,7 @@
         <file category="source" name="CMSIS/RTOS2/RTX/Source/IAR/irq_armv7a.s" condition="IARASM ARMv7-A"/>
       </files>
     </component>
-    <component Cclass="CMSIS" Cgroup="RTOS2" Csub="Keil RTX5" Cvariant="Source_NS" Cversion="5.5.4" Capiversion="2.1.3" condition="RTOS2 RTX5 NS">
+    <component Cclass="CMSIS" Cgroup="RTOS2" Csub="Keil RTX5" Cvariant="Source_NS" Cversion="5.5.5" Capiversion="2.1.3" condition="RTOS2 RTX5 NS">
       <description>CMSIS-RTOS2 RTX5 for Armv8-M/Armv8.1-M Non-Secure Domain (Source)</description>
       <RTE_Components_h>
         <!-- the following content goes into file 'RTE_Components.h' -->
diff --git a/CMSIS/DoxyGen/RTOS2/src/history.txt b/CMSIS/DoxyGen/RTOS2/src/history.txt
index 37664a3..97fdf8c 100644
--- a/CMSIS/DoxyGen/RTOS2/src/history.txt
+++ b/CMSIS/DoxyGen/RTOS2/src/history.txt
@@ -99,6 +99,12 @@
       <th>Description</th>
     </tr>
     <tr>
+      <td>V5.5.5</td>
+      <td>
+       - Added de-allocation of Arm C library thread data (libspace) when thread is terminated.
+      </td>
+    </tr>
+    <tr>
       <td>V5.5.4</td>
       <td>
        - Fixed potential register R1 corruption when calling OS functions from threads multiple times with same arguments (when using high level compiler optimizations).
diff --git a/CMSIS/RTOS2/RTX/Include/rtx_os.h b/CMSIS/RTOS2/RTX/Include/rtx_os.h
index 80e2622..66e4843 100644
--- a/CMSIS/RTOS2/RTX/Include/rtx_os.h
+++ b/CMSIS/RTOS2/RTX/Include/rtx_os.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2021 Arm Limited. All rights reserved.
+ * Copyright (c) 2013-2023 Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -39,8 +39,8 @@
  
 /// Kernel Information
 #define osRtxVersionAPI      20010003   ///< API version (2.1.3)
-#define osRtxVersionKernel   50050004   ///< Kernel version (5.5.4)
-#define osRtxKernelId     "RTX V5.5.4"  ///< Kernel identification string
+#define osRtxVersionKernel   50050005   ///< Kernel version (5.5.5)
+#define osRtxKernelId     "RTX V5.5.5"  ///< Kernel identification string
  
  
 //  ==== Common definitions ====
diff --git a/CMSIS/RTOS2/RTX/Library/fetch_libs.sh b/CMSIS/RTOS2/RTX/Library/fetch_libs.sh
index 68ec43d..5709234 100755
--- a/CMSIS/RTOS2/RTX/Library/fetch_libs.sh
+++ b/CMSIS/RTOS2/RTX/Library/fetch_libs.sh
@@ -1,6 +1,6 @@
 #!/bin/bash
 
-VERSION=5.5.4
+VERSION=5.5.5
 if [ -z "$JENKINS_FAMILY_ENV" ]; then
     ARTIFACTORY_URL=https://artifactory.eu02.arm.com:443/artifactory/mcu.promoted
 else
diff --git a/CMSIS/RTOS2/RTX/Source/rtx_core_ca.h b/CMSIS/RTOS2/RTX/Source/rtx_core_ca.h
index c9e900c..216bda8 100644
--- a/CMSIS/RTOS2/RTX/Source/rtx_core_ca.h
+++ b/CMSIS/RTOS2/RTX/Source/rtx_core_ca.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2021 Arm Limited. All rights reserved.
+ * Copyright (c) 2013-2022 Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: Apache-2.0
  *
diff --git a/CMSIS/RTOS2/RTX/Source/rtx_core_cm.h b/CMSIS/RTOS2/RTX/Source/rtx_core_cm.h
index 2054e71..b1c0156 100644
--- a/CMSIS/RTOS2/RTX/Source/rtx_core_cm.h
+++ b/CMSIS/RTOS2/RTX/Source/rtx_core_cm.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2021 Arm Limited. All rights reserved.
+ * Copyright (c) 2013-2022 Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: Apache-2.0
  *
diff --git a/CMSIS/RTOS2/RTX/Source/rtx_kernel.c b/CMSIS/RTOS2/RTX/Source/rtx_kernel.c
index 68ce828..f7b24f9 100644
--- a/CMSIS/RTOS2/RTX/Source/rtx_kernel.c
+++ b/CMSIS/RTOS2/RTX/Source/rtx_kernel.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2021 Arm Limited. All rights reserved.
+ * Copyright (c) 2013-2023 Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -507,10 +507,10 @@
 //  ==== Library functions ====
 
 /// RTOS Kernel Pre-Initialization Hook
-//lint -esym(759,osRtxKernelPreInit) "Prototype in header"
-//lint -esym(765,osRtxKernelPreInit) "Global scope (can be overridden)"
-//lint -esym(522,osRtxKernelPreInit) "Can be overridden (do not lack side-effects)"
-__WEAK void osRtxKernelPreInit (void) {
+//lint -esym(759,osRtxKernelBeforeInit) "Prototype in header"
+//lint -esym(765,osRtxKernelBeforeInit) "Global scope (can be overridden)"
+//lint -esym(522,osRtxKernelBeforeInit) "Can be overridden (do not lack side-effects)"
+__WEAK void osRtxKernelBeforeInit (void) {
 }
 
 /// RTOS Kernel Error Notification Handler
@@ -527,7 +527,7 @@
 osStatus_t osKernelInitialize (void) {
   osStatus_t status;
 
-  osRtxKernelPreInit();
+  osRtxKernelBeforeInit();
   EvrRtxKernelInitialize();
   if (IsException() || IsIrqMasked()) {
     EvrRtxKernelError((int32_t)osErrorISR);
diff --git a/CMSIS/RTOS2/RTX/Source/rtx_lib.c b/CMSIS/RTOS2/RTX/Source/rtx_lib.c
index adbde77..81ed07d 100644
--- a/CMSIS/RTOS2/RTX/Source/rtx_lib.c
+++ b/CMSIS/RTOS2/RTX/Source/rtx_lib.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2022 Arm Limited. All rights reserved.
+ * Copyright (c) 2013-2023 Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -652,8 +652,8 @@
 
 // RTOS Kernel Pre-Initialization Hook
 #if (defined(OS_EVR_INIT) && (OS_EVR_INIT != 0))
-void osRtxKernelPreInit (void);
-void osRtxKernelPreInit (void) {
+void osRtxKernelBeforeInit (void);
+void osRtxKernelBeforeInit (void) {
   if (osKernelGetState() == osKernelInactive) {
     evr_initialize();
   }
@@ -746,6 +746,24 @@
   return (void *)&os_libspace[n][0];
 }
 
+// Free libspace for specified thread
+static void user_perthread_libspace_free (osThreadId_t id) {
+  uint32_t n;
+
+  for (n = 0U; n < (uint32_t)OS_THREAD_LIBSPACE_NUM; n++) {
+    if (os_libspace_id[n] == id) {
+      os_libspace_id[n] = NULL;
+      break;
+    }
+  }
+}
+
+/// RTOS Thread Before Free Hook
+void osRtxThreadBeforeFree (osThreadId_t id);
+void osRtxThreadBeforeFree (osThreadId_t id) {
+  user_perthread_libspace_free(id);
+}
+
 // Mutex identifier
 typedef void *mutex;
 
diff --git a/CMSIS/RTOS2/RTX/Source/rtx_lib.h b/CMSIS/RTOS2/RTX/Source/rtx_lib.h
index 242f36f..54cfcf7 100644
--- a/CMSIS/RTOS2/RTX/Source/rtx_lib.h
+++ b/CMSIS/RTOS2/RTX/Source/rtx_lib.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2021 Arm Limited. All rights reserved.
+ * Copyright (c) 2013-2023 Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -175,7 +175,7 @@
 //  ==== Library functions ====
 
 // Kernel Library functions
-extern void         osRtxKernelPreInit (void);
+extern void         osRtxKernelBeforeInit (void);
 
 // Thread Library functions
 extern void         osRtxThreadListPut    (os_object_t *object, os_thread_t *thread);
@@ -192,6 +192,7 @@
 #ifdef RTX_STACK_CHECK
 extern bool_t       osRtxThreadStackCheck (const os_thread_t *thread);
 #endif
+extern void         osRtxThreadBeforeFree (os_thread_t *thread);
 extern bool_t       osRtxThreadStartup    (void);
 
 // Timer Library functions
diff --git a/CMSIS/RTOS2/RTX/Source/rtx_thread.c b/CMSIS/RTOS2/RTX/Source/rtx_thread.c
index 5a45d29..fc90ede 100644
--- a/CMSIS/RTOS2/RTX/Source/rtx_thread.c
+++ b/CMSIS/RTOS2/RTX/Source/rtx_thread.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2022 Arm Limited. All rights reserved.
+ * Copyright (c) 2013-2023 Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -1094,6 +1094,8 @@
 /// \param[in]  thread          thread object.
 static void osRtxThreadFree (os_thread_t *thread) {
 
+  osRtxThreadBeforeFree(thread);
+
   // Mark object as inactive and invalid
   thread->state = osRtxThreadInactive;
   thread->id    = osRtxIdInvalid;
@@ -1620,6 +1622,13 @@
 
 //  ==== Library functions ====
 
+/// RTOS Thread Before Free Hook.
+//lint -esym(759,osRtxThreadBeforeFree) "Prototype in header"
+//lint -esym(765,osRtxThreadBeforeFree) "Global scope (can be overridden)"
+__WEAK void osRtxThreadBeforeFree (os_thread_t *thread) {
+  (void)thread;
+}
+
 /// Thread startup (Idle and Timer Thread).
 /// \return true - success, false - failure.
 bool_t osRtxThreadStartup (void) {