summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2016-10-31 13:37:59 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2016-11-02 08:46:47 +0100
commitd271c3bb78f86dd9417a964b019b8e38911064fa (patch)
tree3c36b87c580464cc7f1e5aec89e1137a68759da3
parentposix: Fix timer interval (diff)
downloadrtems-d271c3bb78f86dd9417a964b019b8e38911064fa.tar.bz2
rtems: Add rtems_task_iterate()
Update #2423.
-rw-r--r--cpukit/libcsupport/src/sync.c6
-rw-r--r--cpukit/libmisc/capture/capture-cli.c27
-rw-r--r--cpukit/libmisc/capture/capture.c15
-rw-r--r--cpukit/libmisc/cpuuse/cpuusagereset.c8
-rw-r--r--cpukit/libmisc/cpuuse/cpuusagetop.c49
-rw-r--r--cpukit/libmisc/stackchk/check.c46
-rw-r--r--cpukit/rtems/Makefile.am1
-rw-r--r--cpukit/rtems/include/rtems/rtems/tasks.h32
-rw-r--r--cpukit/rtems/src/taskiterate.c31
-rw-r--r--cpukit/score/Makefile.am1
-rw-r--r--cpukit/score/include/rtems/score/thread.h10
-rw-r--r--cpukit/score/include/rtems/score/threadimpl.h7
-rw-r--r--cpukit/score/src/iterateoverthreads.c45
-rw-r--r--cpukit/score/src/threaditerate.c60
-rw-r--r--testsuites/sptests/sp41/init.c35
-rw-r--r--testsuites/sptests/sp41/sp41.scn9
16 files changed, 245 insertions, 137 deletions
diff --git a/cpukit/libcsupport/src/sync.c b/cpukit/libcsupport/src/sync.c
index 214e42c631..1786b59cb0 100644
--- a/cpukit/libcsupport/src/sync.c
+++ b/cpukit/libcsupport/src/sync.c
@@ -47,7 +47,7 @@ static void sync_wrapper(FILE *f)
}
/* iterate over all FILE *'s for this thread */
-static void sync_per_thread(Thread_Control *t)
+static bool sync_per_thread(Thread_Control *t, void *arg)
{
struct _reent *current_reent;
struct _reent *this_reent;
@@ -64,6 +64,8 @@ static void sync_per_thread(Thread_Control *t)
_fwalk (t->libc_reent, sync_wrapper);
executing->libc_reent = current_reent;
}
+
+ return false;
}
/*
@@ -95,5 +97,5 @@ void sync(void)
/*
* Now walk all the per-thread reentrancy structures.
*/
- rtems_iterate_over_all_threads(sync_per_thread);
+ rtems_task_iterate(sync_per_thread, NULL);
}
diff --git a/cpukit/libmisc/capture/capture-cli.c b/cpukit/libmisc/capture/capture-cli.c
index 05c922be44..d489d9f32a 100644
--- a/cpukit/libmisc/capture/capture-cli.c
+++ b/cpukit/libmisc/capture/capture-cli.c
@@ -42,11 +42,6 @@
#define RTEMS_CAPTURE_CLI_MAX_LOAD_TASKS (20)
/*
- * Counter used to count the number of active tasks.
- */
-static int rtems_capture_cli_task_count = 0;
-
-/*
* The user capture timestamper.
*/
static rtems_capture_timestamp capture_timestamp;
@@ -197,8 +192,8 @@ rtems_capture_cli_disable (int argc RC_UNUSED,
fprintf (stdout, "capture engine disabled.\n");
}
-static void
-rtems_capture_cli_print_task (rtems_tcb *tcb)
+static bool
+rtems_capture_cli_print_task (rtems_tcb *tcb, void *arg)
{
rtems_task_priority ceiling = rtems_capture_watch_get_ceiling ();
rtems_task_priority floor = rtems_capture_watch_get_floor ();
@@ -242,6 +237,7 @@ rtems_capture_cli_print_task (rtems_tcb *tcb)
rtems_capture_watch_global_on () ? 'g' : '-');
}
fprintf (stdout, "\n");
+ return false;
}
/*
@@ -251,10 +247,12 @@ rtems_capture_cli_print_task (rtems_tcb *tcb)
* number of tasks.
*/
-static void
-rtems_capture_cli_count_tasks (rtems_tcb *tcb)
+static bool
+rtems_capture_cli_count_tasks (rtems_tcb *tcb, void *arg)
{
- rtems_capture_cli_task_count++;
+ uint32_t *task_count = arg;
+ ++(*task_count);
+ return false;
}
@@ -271,16 +269,17 @@ rtems_capture_cli_task_list (int argc RC_UNUSED,
bool verbose RC_UNUSED)
{
rtems_capture_time uptime;
+ uint32_t task_count;
rtems_capture_get_time (&uptime);
- rtems_capture_cli_task_count = 0;
- rtems_iterate_over_all_threads (rtems_capture_cli_count_tasks);
+ task_count = 0;
+ rtems_task_iterate (rtems_capture_cli_count_tasks, &task_count);
fprintf (stdout, "uptime: ");
rtems_capture_print_timestamp (uptime);
- fprintf (stdout, "\ntotal %i\n", rtems_capture_cli_task_count);
- rtems_iterate_over_all_threads (rtems_capture_cli_print_task);
+ fprintf (stdout, "\ntotal %" PRIu32 "\n", task_count);
+ rtems_task_iterate (rtems_capture_cli_print_task, NULL);
}
/*
diff --git a/cpukit/libmisc/capture/capture.c b/cpukit/libmisc/capture/capture.c
index 69015c8c1a..41f25aacd5 100644
--- a/cpukit/libmisc/capture/capture.c
+++ b/cpukit/libmisc/capture/capture.c
@@ -279,8 +279,8 @@ rtems_capture_find_control (rtems_name name, rtems_id id)
* This function checks if a new control structure matches
* the given task and sets the control if it does.
*/
-static void
-rtems_capture_initialize_control (rtems_tcb *tcb)
+static bool
+rtems_capture_initialize_control (rtems_tcb *tcb, void *arg)
{
if (tcb->Capture.control == NULL)
{
@@ -305,6 +305,8 @@ rtems_capture_initialize_control (rtems_tcb *tcb)
}
}
}
+
+ return false;
}
static rtems_capture_control*
@@ -342,7 +344,7 @@ rtems_capture_create_control (rtems_name name, rtems_id id)
control->next = capture_controls;
capture_controls = control;
- rtems_iterate_over_all_threads (rtems_capture_initialize_control);
+ _Thread_Iterate (rtems_capture_initialize_control, NULL);
rtems_interrupt_lock_release (&capture_lock_global, &lock_context);
}
@@ -749,10 +751,11 @@ rtems_capture_set_monitor (bool enable)
/*
* This function clears the capture trace flag in the tcb.
*/
-static void
-rtems_capture_flush_tcb (rtems_tcb *tcb)
+static bool
+rtems_capture_flush_tcb (rtems_tcb *tcb, void *arg)
{
tcb->Capture.flags &= ~RTEMS_CAPTURE_TRACED;
+ return false;
}
/*
@@ -776,7 +779,7 @@ rtems_capture_flush (bool prime)
return RTEMS_UNSATISFIED;
}
- rtems_iterate_over_all_threads (rtems_capture_flush_tcb);
+ _Thread_Iterate (rtems_capture_flush_tcb, NULL);
if (prime)
capture_flags_global &= ~(RTEMS_CAPTURE_TRIGGERED | RTEMS_CAPTURE_OVERFLOW);
diff --git a/cpukit/libmisc/cpuuse/cpuusagereset.c b/cpukit/libmisc/cpuuse/cpuusagereset.c
index abfd4db384..608c6a11e8 100644
--- a/cpukit/libmisc/cpuuse/cpuusagereset.c
+++ b/cpukit/libmisc/cpuuse/cpuusagereset.c
@@ -26,8 +26,9 @@
#include "cpuuseimpl.h"
-static void CPU_usage_Per_thread_handler(
- Thread_Control *the_thread
+static bool CPU_usage_Per_thread_handler(
+ Thread_Control *the_thread,
+ void *arg
)
{
const Scheduler_Control *scheduler;
@@ -42,6 +43,7 @@ static void CPU_usage_Per_thread_handler(
_Scheduler_Release_critical( scheduler, &scheduler_lock_context );
_Thread_State_release( the_thread, &state_lock_context );
+ return false;
}
/*
@@ -61,5 +63,5 @@ void rtems_cpu_usage_reset( void )
cpu->cpu_usage_timestamp = CPU_usage_Uptime_at_last_reset;
}
- rtems_iterate_over_all_threads(CPU_usage_Per_thread_handler);
+ rtems_task_iterate(CPU_usage_Per_thread_handler, NULL);
}
diff --git a/cpukit/libmisc/cpuuse/cpuusagetop.c b/cpukit/libmisc/cpuuse/cpuusagetop.c
index 38d5ca4b25..9afa4e292d 100644
--- a/cpukit/libmisc/cpuuse/cpuusagetop.c
+++ b/cpukit/libmisc/cpuuse/cpuusagetop.c
@@ -85,43 +85,6 @@ typedef struct
#define RTEMS_TOP_SORT_CURRENT (4)
#define RTEMS_TOP_SORT_MAX (4)
-/*
- * Private version of the iterator with an arg. This will be moved
- * to the public version in 5.0.
- */
-
-typedef void (*rtems_per_thread_routine_2)( Thread_Control *, void* );
-
-void rtems_iterate_over_all_threads_2(rtems_per_thread_routine_2 routine,
- void* arg);
-
-void rtems_iterate_over_all_threads_2(rtems_per_thread_routine_2 routine,
- void* arg)
-{
- uint32_t i;
- uint32_t api_index;
- Thread_Control *the_thread;
- Objects_Information *information;
-
- if ( !routine )
- return;
-
- for ( api_index = 1 ; api_index <= OBJECTS_APIS_LAST ; api_index++ ) {
- #if !defined(RTEMS_POSIX_API) || defined(RTEMS_DEBUG)
- if ( !_Objects_Information_table[ api_index ] )
- continue;
- #endif
- information = _Objects_Information_table[ api_index ][ 1 ];
- if ( information ) {
- for ( i=1 ; i <= information->maximum ; i++ ) {
- the_thread = (Thread_Control *)information->local_table[ i ];
- if ( the_thread )
- (*routine)(the_thread, arg);
- }
- }
- }
-}
-
static inline bool equal_to_uint32_t( uint32_t * lhs, uint32_t * rhs )
{
if ( *lhs == *rhs )
@@ -190,17 +153,19 @@ print_time(rtems_cpu_usage_data* data,
/*
* Count the number of tasks.
*/
-static void
+static bool
task_counter(Thread_Control *thrad, void* arg)
{
rtems_cpu_usage_data* data = (rtems_cpu_usage_data*) arg;
++data->task_count;
+
+ return false;
}
/*
* Create the sorted table with the current and total usage.
*/
-static void
+static bool
task_usage(Thread_Control* thread, void* arg)
{
rtems_cpu_usage_data* data = (rtems_cpu_usage_data*) arg;
@@ -287,6 +252,8 @@ task_usage(Thread_Control* thread, void* arg)
data->current_usage[j] = current;
break;
}
+
+ return false;
}
/*
@@ -322,7 +289,7 @@ rtems_cpuusage_top_thread (rtems_task_argument arg)
Timestamp_Control load;
data->task_count = 0;
- rtems_iterate_over_all_threads_2(task_counter, data);
+ _Thread_Iterate(task_counter, data);
tasks_size = sizeof(Thread_Control*) * (data->task_count + 1);
usage_size = sizeof(Timestamp_Control) * (data->task_count + 1);
@@ -353,7 +320,7 @@ rtems_cpuusage_top_thread (rtems_task_argument arg)
_Timestamp_Subtract(&data->last_uptime, &data->uptime, &data->period);
data->last_uptime = data->uptime;
- rtems_iterate_over_all_threads_2(task_usage, data);
+ _Thread_Iterate(task_usage, data);
if (data->task_count > data->task_size)
{
diff --git a/cpukit/libmisc/stackchk/check.c b/cpukit/libmisc/stackchk/check.c
index ae4ae79ed8..4c48c5bde3 100644
--- a/cpukit/libmisc/stackchk/check.c
+++ b/cpukit/libmisc/stackchk/check.c
@@ -352,23 +352,20 @@ static inline void *Stack_check_find_high_water_mark(
*
* Try to print out how much stack was actually used by the task.
*/
-static const rtems_printer* printer;
-
-static void Stack_check_Dump_threads_usage(
- Thread_Control *the_thread
+static bool Stack_check_Dump_threads_usage(
+ Thread_Control *the_thread,
+ void *arg
)
{
- uint32_t size, used;
- void *low;
- void *high_water_mark;
- void *current;
- Stack_Control *stack;
- char name[5];
+ uint32_t size, used;
+ void *low;
+ void *high_water_mark;
+ void *current;
+ Stack_Control *stack;
+ char name[5];
+ const rtems_printer *printer;
- /*
- * The pointer passed in for the_thread is guaranteed to be non-NULL from
- * rtems_iterate_over_all_threads() so no need to check it here.
- */
+ printer = arg;
/*
* Obtain interrupt stack information
@@ -376,7 +373,7 @@ static void Stack_check_Dump_threads_usage(
#if (CPU_ALLOCATE_INTERRUPT_STACK == TRUE)
if (the_thread == (Thread_Control *) -1) {
if (!Stack_check_Interrupt_stack.area)
- return;
+ return false;
stack = &Stack_check_Interrupt_stack;
the_thread = 0;
current = 0;
@@ -430,7 +427,7 @@ static void Stack_check_Dump_threads_usage(
rtems_printf( printer, "%8" PRId32 "\n", used );
}
-
+ return false;
}
/*
@@ -453,25 +450,26 @@ static void Stack_check_Dump_threads_usage(
*/
void rtems_stack_checker_report_usage_with_plugin(
- const rtems_printer* printer_
+ const rtems_printer* printer
)
{
- if ( printer != NULL || ! rtems_print_printer_valid ( printer_ ) )
- return;
-
- printer = printer_;
-
rtems_printf( printer, "Stack usage by thread\n");
rtems_printf( printer,
" ID NAME LOW HIGH CURRENT AVAILABLE USED\n"
);
/* iterate over all threads and dump the usage */
- rtems_iterate_over_all_threads( Stack_check_Dump_threads_usage );
+ rtems_task_iterate(
+ Stack_check_Dump_threads_usage,
+ RTEMS_DECONST( rtems_printer *, printer )
+ );
#if (CPU_ALLOCATE_INTERRUPT_STACK == TRUE)
/* dump interrupt stack info if any */
- Stack_check_Dump_threads_usage((Thread_Control *) -1);
+ Stack_check_Dump_threads_usage(
+ (Thread_Control *) -1,
+ RTEMS_DECONST( rtems_printer *, printer )
+ );
#endif
printer = NULL;
diff --git a/cpukit/rtems/Makefile.am b/cpukit/rtems/Makefile.am
index 4be426620c..6ecff9e068 100644
--- a/cpukit/rtems/Makefile.am
+++ b/cpukit/rtems/Makefile.am
@@ -93,6 +93,7 @@ librtems_a_SOURCES += src/taskgetscheduler.c
librtems_a_SOURCES += src/taskident.c
librtems_a_SOURCES += src/taskinitusers.c
librtems_a_SOURCES += src/taskissuspended.c
+librtems_a_SOURCES += src/taskiterate.c
librtems_a_SOURCES += src/taskmode.c
librtems_a_SOURCES += src/taskrestart.c
librtems_a_SOURCES += src/taskresume.c
diff --git a/cpukit/rtems/include/rtems/rtems/tasks.h b/cpukit/rtems/include/rtems/rtems/tasks.h
index 0eaaeca4a3..180e50eed7 100644
--- a/cpukit/rtems/include/rtems/rtems/tasks.h
+++ b/cpukit/rtems/include/rtems/rtems/tasks.h
@@ -513,6 +513,38 @@ rtems_status_code rtems_task_set_scheduler(
rtems_id rtems_task_self(void);
/**
+ * @brief Task visitor.
+ *
+ * @param[in] tcb The task control block.
+ * @param[in] arg The visitor argument.
+ *
+ * @retval true Stop the iteration.
+ * @retval false Otherwise.
+ *
+ * @see rtems_task_iterate().
+ */
+typedef bool ( *rtems_task_visitor )( rtems_tcb *tcb, void *arg );
+
+/**
+ * @brief Iterates over all tasks in the system.
+ *
+ * This operation covers all tasks of all APIs.
+ *
+ * Must be called from task context. This operation obtains and releases the
+ * objects allocator lock. The task visitor is called while owning the objects
+ * allocator lock. It is possible to perform blocking operations in the task
+ * visitor, however, take care that no deadlocks via the object allocator lock
+ * can occur.
+ *
+ * @param[in] visitor The task visitor.
+ * @param[in] arg The visitor argument.
+ */
+void rtems_task_iterate(
+ rtems_task_visitor visitor,
+ void *arg
+);
+
+/**
* @brief Identifies a scheduler by its name.
*
* The scheduler name is determined by the scheduler configuration.
diff --git a/cpukit/rtems/src/taskiterate.c b/cpukit/rtems/src/taskiterate.c
new file mode 100644
index 0000000000..853551b599
--- /dev/null
+++ b/cpukit/rtems/src/taskiterate.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2016 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * 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.
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/rtems/tasks.h>
+#include <rtems/score/threadimpl.h>
+#include <rtems/score/objectimpl.h>
+
+void rtems_task_iterate(
+ rtems_task_visitor visitor,
+ void *arg
+)
+{
+ _Objects_Allocator_lock();
+ _Thread_Iterate( visitor, arg );
+ _Objects_Allocator_unlock();
+}
diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am
index a196ff5dae..bb313a752d 100644
--- a/cpukit/score/Makefile.am
+++ b/cpukit/score/Makefile.am
@@ -310,6 +310,7 @@ libscore_a_SOURCES += src/threadentryadaptornumeric.c
libscore_a_SOURCES += src/threadentryadaptorpointer.c
libscore_a_SOURCES += src/threadgetcputimeused.c
libscore_a_SOURCES += src/threadglobalconstruction.c
+libscore_a_SOURCES += src/threaditerate.c
libscore_a_SOURCES += src/threadtimeout.c
libscore_a_SOURCES += src/threadwaitgetid.c
libscore_a_SOURCES += src/threadyield.c
diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h
index a86d81b4e2..d839b1f9ec 100644
--- a/cpukit/score/include/rtems/score/thread.h
+++ b/cpukit/score/include/rtems/score/thread.h
@@ -834,18 +834,12 @@ void *_Thread_Idle_body(
);
#endif
-/** This defines the type for a method which operates on a single thread.
- */
typedef void (*rtems_per_thread_routine)( Thread_Control * );
-/**
- * @brief Iterates over all threads.
- * This routine iterates over all threads regardless of API and
- * invokes the specified routine.
- */
+/* Use rtems_task_iterate() instead */
void rtems_iterate_over_all_threads(
rtems_per_thread_routine routine
-);
+) RTEMS_DEPRECATED;
/**
* @brief Thread control add-on.
diff --git a/cpukit/score/include/rtems/score/threadimpl.h b/cpukit/score/include/rtems/score/threadimpl.h
index 7b978ea477..51d9d473bf 100644
--- a/cpukit/score/include/rtems/score/threadimpl.h
+++ b/cpukit/score/include/rtems/score/threadimpl.h
@@ -83,6 +83,13 @@ extern Thread_Control *_Thread_Allocated_fp;
RTEMS_CONTAINER_OF( node, Thread_Control, Resource_node )
#endif
+typedef bool ( *Thread_Visitor )( Thread_Control *the_thread, void *arg );
+
+void _Thread_Iterate(
+ Thread_Visitor visitor,
+ void *arg
+);
+
void _Thread_Initialize_information(
Thread_Information *information,
Objects_APIs the_api,
diff --git a/cpukit/score/src/iterateoverthreads.c b/cpukit/score/src/iterateoverthreads.c
index 8933352298..e829fc9edb 100644
--- a/cpukit/score/src/iterateoverthreads.c
+++ b/cpukit/score/src/iterateoverthreads.c
@@ -18,37 +18,28 @@
#include "config.h"
#endif
-#include <rtems/score/thread.h>
-#include <rtems/score/objectimpl.h>
+#include <rtems/score/threadimpl.h>
-void rtems_iterate_over_all_threads(rtems_per_thread_routine routine)
-{
- uint32_t i;
- uint32_t api_index;
- Thread_Control *the_thread;
- Objects_Information *information;
-
- if ( !routine )
- return;
+typedef struct {
+ rtems_per_thread_routine routine;
+} routine_arg;
- for ( api_index = 1 ; api_index <= OBJECTS_APIS_LAST ; api_index++ ) {
- #if !defined(RTEMS_POSIX_API) || defined(RTEMS_DEBUG)
- if ( !_Objects_Information_table[ api_index ] )
- continue;
- #endif
-
- information = _Objects_Information_table[ api_index ][ 1 ];
- if ( !information )
- continue;
+static bool routine_adaptor( rtems_tcb *tcb, void *arg )
+{
+ routine_arg *ra;
- for ( i=1 ; i <= information->maximum ; i++ ) {
- the_thread = (Thread_Control *)information->local_table[ i ];
+ ra = arg;
+ ( *ra->routine )( tcb );
+ return false;
+}
- if ( !the_thread )
- continue;
+void rtems_iterate_over_all_threads( rtems_per_thread_routine routine )
+{
+ routine_arg arg = {
+ .routine = routine
+ };
- (*routine)(the_thread);
- }
+ if ( routine != NULL ) {
+ _Thread_Iterate( routine_adaptor, &arg );
}
-
}
diff --git a/cpukit/score/src/threaditerate.c b/cpukit/score/src/threaditerate.c
new file mode 100644
index 0000000000..0f9a1bef44
--- /dev/null
+++ b/cpukit/score/src/threaditerate.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2016 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * 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.
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/score/threadimpl.h>
+
+void _Thread_Iterate(
+ Thread_Visitor visitor,
+ void *arg
+)
+{
+ int api_index;
+
+ for ( api_index = 1 ; api_index <= OBJECTS_APIS_LAST ; ++api_index ) {
+ const Objects_Information *information;
+ Objects_Maximum i;
+
+#if !defined(RTEMS_POSIX_API)
+ if ( _Objects_Information_table[ api_index ] == NULL ) {
+ continue;
+ }
+#endif
+
+ information = _Objects_Information_table[ api_index ][ 1 ];
+
+ if ( information == NULL ) {
+ continue;
+ }
+
+ for ( i = 1 ; i <= information->maximum ; ++i ) {
+ Thread_Control *the_thread;
+
+ the_thread = (Thread_Control *) information->local_table[ i ];
+
+ if ( the_thread != NULL ) {
+ bool done;
+
+ done = (* visitor )( the_thread, arg );
+
+ if ( done ) {
+ return;
+ }
+ }
+ }
+ }
+}
diff --git a/testsuites/sptests/sp41/init.c b/testsuites/sptests/sp41/init.c
index c4846086b6..04b855b352 100644
--- a/testsuites/sptests/sp41/init.c
+++ b/testsuites/sptests/sp41/init.c
@@ -11,27 +11,31 @@
#include "config.h"
#endif
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+
#include <tmacros.h>
#include <rtems/score/objectimpl.h>
const char rtems_test_name[] = "SP 41";
-/* forward declarations to avoid warnings */
-rtems_task Init(rtems_task_argument argument);
-void iterator(Thread_Control *thread);
+static bool visitor( Thread_Control *thread, void *arg )
+{
+ int *counter = arg;
+ ++( *counter );
+ return false;
+}
-void iterator(
- Thread_Control *thread
-)
+static void iterator( Thread_Control *thread )
{
}
-rtems_task Init(
+static rtems_task Init(
rtems_task_argument ignored
)
{
void *tmp;
+ int counter;
TEST_BEGIN();
@@ -39,9 +43,22 @@ rtems_task Init(
tmp = _Objects_Information_table[ OBJECTS_CLASSIC_API ][ 1 ];
_Objects_Information_table[ OBJECTS_CLASSIC_API ][ 1 ] = NULL;
- puts( "Init - rtems_iterate_over_all_threads" );
- rtems_iterate_over_all_threads(iterator);
+ puts( "Init - rtems_task_iterate - NULL table" );
+ counter = 0;
+ rtems_task_iterate( visitor, &counter );
_Objects_Information_table[ OBJECTS_CLASSIC_API ][ 1 ] = tmp;
+ rtems_test_assert( counter == 1 );
+
+ puts( "Init - rtems_task_iterate - normal" );
+ counter = 0;
+ rtems_task_iterate( visitor, &counter );
+ rtems_test_assert( counter == 2 );
+
+ puts( "Init - rtems_iterate_over_all_threads - NULL" );
+ rtems_iterate_over_all_threads( NULL );
+
+ puts( "Init - rtems_iterate_over_all_threads - iterator" );
+ rtems_iterate_over_all_threads( iterator );
TEST_END();
rtems_test_exit(0);
diff --git a/testsuites/sptests/sp41/sp41.scn b/testsuites/sptests/sp41/sp41.scn
index 02933ae252..9a43b0ad92 100644
--- a/testsuites/sptests/sp41/sp41.scn
+++ b/testsuites/sptests/sp41/sp41.scn
@@ -1,4 +1,7 @@
-*** TEST 41 ***
+*** BEGIN OF TEST SP 41 ***
Init - overwrite internal value to trip case
-Init - rtems_iterate_over_all_threads
-*** END OF TEST 41 ***
+Init - rtems_task_iterate - NULL table
+Init - rtems_task_iterate - normal
+Init - rtems_iterate_over_all_threads - NULL
+Init - rtems_iterate_over_all_threads - iterator
+*** END OF TEST SP 41 ***