summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cpukit/include/rtems/confdefs/percpu.h18
-rw-r--r--cpukit/include/rtems/confdefs/wkspace.h16
-rw-r--r--cpukit/include/rtems/config.h12
-rw-r--r--cpukit/include/rtems/score/stack.h24
-rw-r--r--cpukit/score/src/stackallocatorforidle.c59
-rw-r--r--cpukit/score/src/threadcreateidle.c12
-rw-r--r--spec/build/cpukit/librtemscpu.yml1
-rw-r--r--spec/build/testsuites/sptests/grp.yml4
-rw-r--r--spec/build/testsuites/sptests/spstkalloc03.yml19
-rw-r--r--spec/build/testsuites/sptests/spstkalloc04.yml19
-rw-r--r--testsuites/sptests/spstkalloc03/init.c103
-rw-r--r--testsuites/sptests/spstkalloc03/spstkalloc03.doc19
-rw-r--r--testsuites/sptests/spstkalloc03/spstkalloc03.scn2
-rw-r--r--testsuites/sptests/spstkalloc04/init.c82
-rw-r--r--testsuites/sptests/spstkalloc04/spstkalloc04.doc20
-rw-r--r--testsuites/sptests/spstkalloc04/spstkalloc04.scn2
16 files changed, 404 insertions, 8 deletions
diff --git a/cpukit/include/rtems/confdefs/percpu.h b/cpukit/include/rtems/confdefs/percpu.h
index badb616988..3bea8340cb 100644
--- a/cpukit/include/rtems/confdefs/percpu.h
+++ b/cpukit/include/rtems/confdefs/percpu.h
@@ -134,11 +134,19 @@ RTEMS_DEFINE_GLOBAL_SYMBOL(
const size_t _Thread_Idle_stack_size = CONFIGURE_IDLE_TASK_STACK_SIZE;
-char _Thread_Idle_stacks[
- _CONFIGURE_MAXIMUM_PROCESSORS
- * ( CONFIGURE_IDLE_TASK_STACK_SIZE + CPU_IDLE_TASK_IS_FP * CONTEXT_FP_SIZE )
-] RTEMS_ALIGNED( CPU_INTERRUPT_STACK_ALIGNMENT )
-RTEMS_SECTION( ".rtemsstack.idle" );
+/*
+ * If the user provides a custom idle stack allocator, then we do not need
+ * memory reserved for the stacks but the symbol is still referenced in
+ * threadcreateidle.c. The code path just never uses it. Make it minimal
+ * size to proceed.
+ */
+#ifndef CONFIGURE_TASK_STACK_ALLOCATOR_FOR_IDLE
+ char _Thread_Idle_stacks[
+ _CONFIGURE_MAXIMUM_PROCESSORS
+ * ( CONFIGURE_IDLE_TASK_STACK_SIZE + CPU_IDLE_TASK_IS_FP * CONTEXT_FP_SIZE )
+ ] RTEMS_ALIGNED( CPU_INTERRUPT_STACK_ALIGNMENT )
+ RTEMS_SECTION( ".rtemsstack.idle" );
+#endif
#if defined(CONFIGURE_IDLE_TASK_INITIALIZES_APPLICATION) && \
!defined(CONFIGURE_IDLE_TASK_BODY)
diff --git a/cpukit/include/rtems/confdefs/wkspace.h b/cpukit/include/rtems/confdefs/wkspace.h
index 1db4f2d09d..82de8633bf 100644
--- a/cpukit/include/rtems/confdefs/wkspace.h
+++ b/cpukit/include/rtems/confdefs/wkspace.h
@@ -167,12 +167,14 @@ const uintptr_t _Stack_Space_size = _CONFIGURE_STACK_SPACE_SIZE;
#pragma GCC diagnostic ignored "-Wpragmas"
#pragma GCC diagnostic ignored "-Wtautological-pointer-compare"
+ /* Custom allocator may or may not use the work space. */
#ifdef CONFIGURE_TASK_STACK_ALLOCATOR_AVOIDS_WORK_SPACE
const bool _Stack_Allocator_avoids_workspace = true;
#else
const bool _Stack_Allocator_avoids_workspace = false;
#endif
+ /* Custom allocator may or may not need initialization. */
#ifdef CONFIGURE_TASK_STACK_ALLOCATOR_INIT
const Stack_Allocator_initialize _Stack_Allocator_initialize =
_CONFIGURE_ASSERT_NOT_NULL(
@@ -187,6 +189,7 @@ const uintptr_t _Stack_Space_size = _CONFIGURE_STACK_SPACE_SIZE;
);
#endif
+ /* Custom allocator must include allocate and free */
const Stack_Allocator_allocate _Stack_Allocator_allocate =
_CONFIGURE_ASSERT_NOT_NULL(
Stack_Allocator_allocate,
@@ -200,11 +203,24 @@ const uintptr_t _Stack_Space_size = _CONFIGURE_STACK_SPACE_SIZE;
);
#pragma GCC diagnostic pop
+
+/*
+ * Must provide both a custom stack allocator and deallocator
+ */
#elif defined(CONFIGURE_TASK_STACK_ALLOCATOR) \
|| defined(CONFIGURE_TASK_STACK_DEALLOCATOR)
#error "CONFIGURE_TASK_STACK_ALLOCATOR and CONFIGURE_TASK_STACK_DEALLOCATOR must be both defined or both undefined"
#endif
+/*
+ * Custom IDLE thread stacks allocator. If this is provided, it is assumed
+ * that the allocator is providing its own memory for these stacks.
+ */
+#ifdef CONFIGURE_TASK_STACK_ALLOCATOR_FOR_IDLE
+ const Stack_Allocator_allocate_for_idle _Stack_Allocator_allocate_for_idle =
+ CONFIGURE_TASK_STACK_ALLOCATOR_FOR_IDLE;
+#endif
+
#ifdef CONFIGURE_DIRTY_MEMORY
RTEMS_SYSINIT_ITEM(
_Memory_Dirty_free_areas,
diff --git a/cpukit/include/rtems/config.h b/cpukit/include/rtems/config.h
index afcee4381b..7b15bc34a2 100644
--- a/cpukit/include/rtems/config.h
+++ b/cpukit/include/rtems/config.h
@@ -368,6 +368,18 @@ uint32_t rtems_configuration_get_maximum_extensions( void );
*/
#define rtems_configuration_get_stack_free_hook() _Stack_Allocator_free
+/**
+ * @ingroup RTEMSAPIConfig
+ *
+ * @brief Gets the IDLE thread stack allocator hook configured for this
+ * application.
+ *
+ * @return Returns the IDLE thread stack allocator hook configured for this
+ * application.
+ */
+#define rtems_configuration_get_stack_allocate_for_idle_hook() \
+ (_Stack_Allocator_allocate_for_idle)
+
/* Generated from spec:/rtems/config/if/get-stack-space-size */
/**
diff --git a/cpukit/include/rtems/score/stack.h b/cpukit/include/rtems/score/stack.h
index 23421cf7ae..ffa6368ba5 100644
--- a/cpukit/include/rtems/score/stack.h
+++ b/cpukit/include/rtems/score/stack.h
@@ -81,6 +81,23 @@ typedef void *( *Stack_Allocator_allocate )( size_t stack_size );
typedef void ( *Stack_Allocator_free )( void *addr );
/**
+ * @brief Stack allocator allocate for idle handler.
+ *
+ * The allocate for idle handler is optional even when the user thread stack
+ * allocator and deallocator are configured.
+ *
+ * @param cpu Index of the CPU for the IDLE thread using this stack
+ * @param stack_size The size of the stack area to allocate in bytes.
+ *
+ * @retval NULL Not enough memory.
+ * @retval other Pointer to begin of stack area.
+ */
+typedef void *( *Stack_Allocator_allocate_for_idle )(
+ uint32_t cpu,
+ size_t stack_size
+);
+
+/**
* @brief The minimum stack size.
*
* Application provided via <rtems/confdefs.h>.
@@ -130,6 +147,13 @@ extern const Stack_Allocator_free _Stack_Allocator_free;
void _Stack_Allocator_do_initialize( void );
/** @} */
+/**
+ * @brief The stack allocator allocate stack for idle thread handler.
+ *
+ * Application provided via <rtems/confdefs.h>.
+ */
+extern const Stack_Allocator_allocate_for_idle
+ _Stack_Allocator_allocate_for_idle;
#ifdef __cplusplus
}
diff --git a/cpukit/score/src/stackallocatorforidle.c b/cpukit/score/src/stackallocatorforidle.c
new file mode 100644
index 0000000000..7c4fd10c7d
--- /dev/null
+++ b/cpukit/score/src/stackallocatorforidle.c
@@ -0,0 +1,59 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (C) 2021 OAR Corporation
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/score/stack.h>
+#include <rtems/score/thread.h>
+
+/**
+ * @brief Default stack allocator allocate for idle handler.
+ *
+ * The allocate for idle handler is optional even when the user thread stack
+ * allocator and deallocator are configured.
+ *
+ * The default allocator for IDLE thread stacks gets the memory from a
+ * statically allocated area provided via confdefs.h.
+ *
+ * @param cpu Index of the CPU for the IDLE thread using this stack
+ * @param stack_size The size of the stack area to allocate in bytes.
+ *
+ * @retval NULL Not enough memory (never returned).
+ * @retval other Pointer to begin of stack area.
+ */
+static void *_Stack_Allocator_allocate_for_idle_default(
+ uint32_t cpu,
+ size_t stack_size
+)
+{
+ return &_Thread_Idle_stacks[ cpu * stack_size ];
+}
+
+const Stack_Allocator_allocate_for_idle _Stack_Allocator_allocate_for_idle =
+ _Stack_Allocator_allocate_for_idle_default;
diff --git a/cpukit/score/src/threadcreateidle.c b/cpukit/score/src/threadcreateidle.c
index f5ffc9bad8..86e117e70f 100644
--- a/cpukit/score/src/threadcreateidle.c
+++ b/cpukit/score/src/threadcreateidle.c
@@ -49,9 +49,15 @@ static void _Thread_Create_idle_for_CPU( Per_CPU_Control *cpu )
config.is_preemptible = true;
config.stack_size = _Thread_Idle_stack_size
+ CPU_IDLE_TASK_IS_FP * CONTEXT_FP_SIZE;
- config.stack_area = &_Thread_Idle_stacks[
- _Per_CPU_Get_index( cpu ) * config.stack_size
- ];
+
+ /*
+ * The IDLE thread stacks may be statically allocated or there may be a
+ * custom allocator provided just as with user threads.
+ */
+ config.stack_area = (*_Stack_Allocator_allocate_for_idle)(
+ _Per_CPU_Get_index( cpu ),
+ config.stack_size
+ );
/*
* The entire workspace is zeroed during its initialization. Thus, all
diff --git a/spec/build/cpukit/librtemscpu.yml b/spec/build/cpukit/librtemscpu.yml
index c0f8f6d670..68f3d448cc 100644
--- a/spec/build/cpukit/librtemscpu.yml
+++ b/spec/build/cpukit/librtemscpu.yml
@@ -1527,6 +1527,7 @@ source:
- cpukit/score/src/semaphore.c
- cpukit/score/src/smpbarrierwait.c
- cpukit/score/src/stackallocator.c
+- cpukit/score/src/stackallocatorforidle.c
- cpukit/score/src/stackallocatorfree.c
- cpukit/score/src/stackallocatorinit.c
- cpukit/score/src/thread.c
diff --git a/spec/build/testsuites/sptests/grp.yml b/spec/build/testsuites/sptests/grp.yml
index d3cd53fb4a..6b16c115ba 100644
--- a/spec/build/testsuites/sptests/grp.yml
+++ b/spec/build/testsuites/sptests/grp.yml
@@ -396,6 +396,10 @@ links:
- role: build-dependency
uid: spstkalloc02
- role: build-dependency
+ uid: spstkalloc03
+- role: build-dependency
+ uid: spstkalloc04
+- role: build-dependency
uid: spsysinit01
- role: build-dependency
uid: spsyslock01
diff --git a/spec/build/testsuites/sptests/spstkalloc03.yml b/spec/build/testsuites/sptests/spstkalloc03.yml
new file mode 100644
index 0000000000..fbdb91bd6f
--- /dev/null
+++ b/spec/build/testsuites/sptests/spstkalloc03.yml
@@ -0,0 +1,19 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+build-type: test-program
+cflags: []
+copyrights:
+- Copyright (C) 2030 embedded brains GmbH (http://www.embedded-brains.de)
+cppflags: []
+cxxflags: []
+enabled-by: true
+features: c cprogram
+includes: []
+ldflags: []
+links: []
+source:
+- testsuites/sptests/spstkalloc03/init.c
+stlib: []
+target: testsuites/sptests/spstkalloc03.exe
+type: build
+use-after: []
+use-before: []
diff --git a/spec/build/testsuites/sptests/spstkalloc04.yml b/spec/build/testsuites/sptests/spstkalloc04.yml
new file mode 100644
index 0000000000..64340ed8f7
--- /dev/null
+++ b/spec/build/testsuites/sptests/spstkalloc04.yml
@@ -0,0 +1,19 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+build-type: test-program
+cflags: []
+copyrights:
+- Copyright (C) 2040 embedded brains GmbH (http://www.embedded-brains.de)
+cppflags: []
+cxxflags: []
+enabled-by: true
+features: c cprogram
+includes: []
+ldflags: []
+links: []
+source:
+- testsuites/sptests/spstkalloc04/init.c
+stlib: []
+target: testsuites/sptests/spstkalloc04.exe
+type: build
+use-after: []
+use-before: []
diff --git a/testsuites/sptests/spstkalloc03/init.c b/testsuites/sptests/spstkalloc03/init.c
new file mode 100644
index 0000000000..348afe7328
--- /dev/null
+++ b/testsuites/sptests/spstkalloc03/init.c
@@ -0,0 +1,103 @@
+/*
+ * COPYRIGHT (c) 2021.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <tmacros.h>
+
+#include <rtems/score/percpu.h>
+
+const char rtems_test_name[] = "SPSTKALLOC 3";
+
+static int thread_stacks_count = 0xff;
+
+static rtems_task Init(
+ rtems_task_argument ignored
+)
+{
+ rtems_print_printer_fprintf_putc(&rtems_test_printer);
+ TEST_BEGIN();
+ rtems_test_assert(thread_stacks_count == 2);
+ TEST_END();
+ rtems_test_exit( 0 );
+}
+
+static uint8_t stack_memory[RTEMS_MINIMUM_STACK_SIZE * 4];
+
+static int stack_offset_next;
+
+static void *allocate_helper(size_t size)
+{
+ size_t next;
+ void *alloc;
+
+ next = stack_offset_next + size;
+ rtems_test_assert( next < sizeof(stack_memory) );
+
+ alloc = &stack_memory[stack_offset_next];
+ stack_offset_next = next;
+ return alloc;
+}
+
+static void thread_stacks_initialize(size_t stack_space_size)
+{
+ rtems_test_assert(thread_stacks_count == 0xff);
+ thread_stacks_count = 0;
+}
+
+static void *thread_stacks_allocate(size_t stack_size)
+{
+ rtems_test_assert(thread_stacks_count == 1);
+ thread_stacks_count++;
+ return allocate_helper(stack_size);
+}
+
+static void thread_stacks_free(void *addr)
+{
+ rtems_test_assert(false);
+}
+
+static void *thread_stacks_allocate_for_idle(
+ uint32_t cpu,
+ size_t stack_size
+)
+{
+ rtems_test_assert(thread_stacks_count == 0);
+ thread_stacks_count++;
+ return allocate_helper(stack_size);
+}
+
+/*
+ * Configure the thread stack allocators to not use the workspace. This should
+ * eliminate all uses of the Workspace for most BSPs.
+ */
+#define CONFIGURE_TASK_STACK_ALLOCATOR_AVOIDS_WORK_SPACE
+#define CONFIGURE_TASK_STACK_ALLOCATOR_INIT thread_stacks_initialize
+#define CONFIGURE_TASK_STACK_ALLOCATOR thread_stacks_allocate
+#define CONFIGURE_TASK_STACK_DEALLOCATOR thread_stacks_free
+#define CONFIGURE_TASK_STACK_ALLOCATOR_FOR_IDLE thread_stacks_allocate_for_idle
+
+
+/* NOTICE: the clock driver is explicitly disabled */
+#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
+
+#define CONFIGURE_MAXIMUM_TASKS 1
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT_TASK_ATTRIBUTES RTEMS_FLOATING_POINT
+
+#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
+
+#define CONFIGURE_INIT
+#include <rtems/confdefs.h>
diff --git a/testsuites/sptests/spstkalloc03/spstkalloc03.doc b/testsuites/sptests/spstkalloc03/spstkalloc03.doc
new file mode 100644
index 0000000000..797716b623
--- /dev/null
+++ b/testsuites/sptests/spstkalloc03/spstkalloc03.doc
@@ -0,0 +1,19 @@
+# COPYRIGHT (c) 2021.
+# On-Line Applications Research Corporation (OAR).
+#
+# The license and distribution terms for this file may be
+# found in the file LICENSE in this distribution or at
+# http://www.rtems.org/license/LICENSE.
+#
+
+This file describes the directives and concepts tested by this test set.
+
+test set name: spstkalloc03
+
+directives:
+
+concepts:
+
++ Ensure that the task stack allocator including IDLE thread
+ stack allocator works.
+
diff --git a/testsuites/sptests/spstkalloc03/spstkalloc03.scn b/testsuites/sptests/spstkalloc03/spstkalloc03.scn
new file mode 100644
index 0000000000..45c67ef1fb
--- /dev/null
+++ b/testsuites/sptests/spstkalloc03/spstkalloc03.scn
@@ -0,0 +1,2 @@
+*** BEGIN OF TEST SPSTKALLOC 3 ***
+*** END OF TEST SPSTKALLOC 3 ***
diff --git a/testsuites/sptests/spstkalloc04/init.c b/testsuites/sptests/spstkalloc04/init.c
new file mode 100644
index 0000000000..16f4ec65ca
--- /dev/null
+++ b/testsuites/sptests/spstkalloc04/init.c
@@ -0,0 +1,82 @@
+/*
+ * COPYRIGHT (c) 2021.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <tmacros.h>
+
+#include <rtems/score/percpu.h>
+
+const char rtems_test_name[] = "SPSTKALLOC 4";
+
+static int thread_stacks_count = 0;
+
+static rtems_task Init(
+ rtems_task_argument ignored
+)
+{
+ rtems_print_printer_fprintf_putc(&rtems_test_printer);
+ TEST_BEGIN();
+ rtems_test_assert(thread_stacks_count == 1);
+ TEST_END();
+ rtems_test_exit( 0 );
+}
+
+static uint8_t stack_memory[RTEMS_MINIMUM_STACK_SIZE * 4];
+
+static int stack_offset_next;
+
+static void *allocate_helper(size_t size)
+{
+ size_t next;
+ void *alloc;
+
+ next = stack_offset_next + size;
+ rtems_test_assert( next < sizeof(stack_memory) );
+
+ alloc = &stack_memory[stack_offset_next];
+ stack_offset_next = next;
+ return alloc;
+}
+
+static void *thread_stacks_allocate_for_idle(
+ uint32_t cpu,
+ size_t stack_size
+)
+{
+ rtems_test_assert(thread_stacks_count == 0);
+ thread_stacks_count++;
+ return allocate_helper(stack_size);
+}
+
+/*
+ * Configure the IDLE thread stack allocators. This is a special
+ * case where there is an IDLE thread stack allocator but no custom
+ * allocator set for other threads.
+ */
+#define CONFIGURE_TASK_STACK_ALLOCATOR_FOR_IDLE thread_stacks_allocate_for_idle
+
+
+/* NOTICE: the clock driver is explicitly disabled */
+#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
+
+#define CONFIGURE_MAXIMUM_TASKS 1
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT_TASK_ATTRIBUTES RTEMS_FLOATING_POINT
+
+#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
+
+#define CONFIGURE_INIT
+#include <rtems/confdefs.h>
diff --git a/testsuites/sptests/spstkalloc04/spstkalloc04.doc b/testsuites/sptests/spstkalloc04/spstkalloc04.doc
new file mode 100644
index 0000000000..a1ed5b22cb
--- /dev/null
+++ b/testsuites/sptests/spstkalloc04/spstkalloc04.doc
@@ -0,0 +1,20 @@
+# COPYRIGHT (c) 2021.
+# On-Line Applications Research Corporation (OAR).
+#
+# The license and distribution terms for this file may be
+# found in the file LICENSE in this distribution or at
+# http://www.rtems.org/license/LICENSE.
+#
+
+This file describes the directives and concepts tested by this test set.
+
+test set name: spstkalloc04
+
+directives:
+
+concepts:
+
++ Ensure that the task stack allocator including IDLE thread
+ stack allocator works when a custom allocator is NOT provided
+ for other threads.
+
diff --git a/testsuites/sptests/spstkalloc04/spstkalloc04.scn b/testsuites/sptests/spstkalloc04/spstkalloc04.scn
new file mode 100644
index 0000000000..f0919ec2d4
--- /dev/null
+++ b/testsuites/sptests/spstkalloc04/spstkalloc04.scn
@@ -0,0 +1,2 @@
+*** BEGIN OF TEST SPSTKALLOC 4 ***
+*** END OF TEST SPSTKALLOC 4 ***