[PATCH 1/2] rtems: Add rtems_task_iterate()

Sebastian Huber sebastian.huber at embedded-brains.de
Mon Oct 31 13:47:34 UTC 2016


Close #2423.
---
 cpukit/libcsupport/src/sync.c                 |  6 ++-
 cpukit/libmisc/capture/capture-cli.c          | 27 ++++++------
 cpukit/libmisc/capture/capture.c              | 15 ++++---
 cpukit/libmisc/cpuuse/cpuusagereset.c         |  8 ++--
 cpukit/libmisc/cpuuse/cpuusagetop.c           | 49 ++++------------------
 cpukit/libmisc/stackchk/check.c               | 46 ++++++++++----------
 cpukit/rtems/Makefile.am                      |  1 +
 cpukit/rtems/include/rtems/rtems/tasks.h      | 32 ++++++++++++++
 cpukit/rtems/src/taskiterate.c                | 31 ++++++++++++++
 cpukit/score/Makefile.am                      |  1 +
 cpukit/score/include/rtems/score/thread.h     | 10 +----
 cpukit/score/include/rtems/score/threadimpl.h |  7 ++++
 cpukit/score/src/iterateoverthreads.c         | 45 ++++++++------------
 cpukit/score/src/threaditerate.c              | 60 +++++++++++++++++++++++++++
 testsuites/sptests/sp41/init.c                | 35 ++++++++++++----
 testsuites/sptests/sp41/sp41.scn              |  9 ++--
 16 files changed, 245 insertions(+), 137 deletions(-)
 create mode 100644 cpukit/rtems/src/taskiterate.c
 create mode 100644 cpukit/score/src/threaditerate.c

diff --git a/cpukit/libcsupport/src/sync.c b/cpukit/libcsupport/src/sync.c
index 214e42c..1786b59 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 05c922b..d489d9f 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 69015c8..41f25aa 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 f6cf7dd..507044a 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 38d5ca4..9afa4e2 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 ae4ae79..4c48c5b 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 4be4266..6ecff9e 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 0eaaeca..180e50e 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 0000000..853551b
--- /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 at 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 528c3fe..58f9e65 100644
--- a/cpukit/score/Makefile.am
+++ b/cpukit/score/Makefile.am
@@ -307,6 +307,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/threadscheduler.c
 libscore_a_SOURCES += src/threadtimeout.c
 libscore_a_SOURCES += src/threadwaitgetid.c
diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h
index e98059e..ff7f13b 100644
--- a/cpukit/score/include/rtems/score/thread.h
+++ b/cpukit/score/include/rtems/score/thread.h
@@ -839,18 +839,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 f96c4b0..5425978 100644
--- a/cpukit/score/include/rtems/score/threadimpl.h
+++ b/cpukit/score/include/rtems/score/threadimpl.h
@@ -82,6 +82,13 @@ extern Thread_Control *_Thread_Allocated_fp;
   RTEMS_CONTAINER_OF( node, Thread_Control, Scheduler.Help_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 8933352..e829fc9 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 0000000..0f9a1be
--- /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 at 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 c484608..04b855b 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 02933ae..9a43b0a 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 ***
-- 
1.8.4.5



More information about the devel mailing list