[PATCH] Add a user argument to 'rtems_iterate_over_all_threads'.

Chris Johns chrisj at rtems.org
Wed Jul 13 06:07:43 UTC 2016


Pass a user argument to the iterator to allow local data.

Update all users in the source tree.
---
 cpukit/libcsupport/src/sync.c             |  8 +++--
 cpukit/libmisc/capture/capture-cli.c      | 15 ++++++----
 cpukit/libmisc/capture/capture.c          | 15 ++++++----
 cpukit/libmisc/cpuuse/cpuusagereset.c     |  9 ++++--
 cpukit/libmisc/cpuuse/cpuusagetop.c       | 50 +++++--------------------------
 cpukit/libmisc/stackchk/check.c           | 11 +++----
 cpukit/score/include/rtems/score/thread.h | 24 +++++++++++----
 cpukit/score/src/iterateoverthreads.c     |  9 ++++--
 testsuites/sptests/sp41/init.c            |  8 +++--
 9 files changed, 73 insertions(+), 76 deletions(-)

diff --git a/cpukit/libcsupport/src/sync.c b/cpukit/libcsupport/src/sync.c
index 214e42c..74840ed 100644
--- a/cpukit/libcsupport/src/sync.c
+++ b/cpukit/libcsupport/src/sync.c
@@ -1,7 +1,7 @@
 /**
  *  @file
  *
- *  @brief Synchronize Data on Disk with Memory 
+ *  @brief Synchronize Data on Disk with Memory
  *  @ingroup libcsupport
  */
 
@@ -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 *user RTEMS_UNUSED)
 {
    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_iterate_over_all_threads(sync_per_thread, NULL);
 }
diff --git a/cpukit/libmisc/capture/capture-cli.c b/cpukit/libmisc/capture/capture-cli.c
index b9c2edc..6c457c9 100644
--- a/cpukit/libmisc/capture/capture-cli.c
+++ b/cpukit/libmisc/capture/capture-cli.c
@@ -197,8 +197,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 *user RC_UNUSED)
 {
   rtems_task_priority   ceiling = rtems_capture_watch_get_ceiling ();
   rtems_task_priority   floor = rtems_capture_watch_get_floor ();
@@ -235,6 +235,8 @@ rtems_capture_cli_print_task (rtems_tcb *tcb)
              rtems_capture_watch_global_on () ? 'g' : '-');
   }
   fprintf (stdout, "\n");
+
+  return false;
 }
 
 /*
@@ -244,10 +246,11 @@ 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 *user RC_UNUSED)
 {
   rtems_capture_cli_task_count++;
+  return false;
 }
 
 
@@ -268,12 +271,12 @@ rtems_capture_cli_task_list (int                                argc RC_UNUSED,
   rtems_capture_time (&uptime);
 
   rtems_capture_cli_task_count = 0;
-  rtems_iterate_over_all_threads (rtems_capture_cli_count_tasks);
+  rtems_iterate_over_all_threads (rtems_capture_cli_count_tasks, NULL);
 
   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);
+  rtems_iterate_over_all_threads (rtems_capture_cli_print_task, NULL);
 }
 
 /*
diff --git a/cpukit/libmisc/capture/capture.c b/cpukit/libmisc/capture/capture.c
index 6879a37..464b8de 100644
--- a/cpukit/libmisc/capture/capture.c
+++ b/cpukit/libmisc/capture/capture.c
@@ -276,8 +276,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 *user RTEMS_UNUSED)
 {
   rtems_name                   name;
   rtems_capture_control_t*     control;
@@ -291,6 +291,8 @@ rtems_capture_initialize_control (rtems_tcb *tcb)
   if (rtems_capture_match_name_id (control->name, control->id,
                                    name, tcb->Object.id))
     tcb->Capture.control = control;
+
+  return false;
 }
 
 /*
@@ -330,7 +332,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);
+    rtems_iterate_over_all_threads (rtems_capture_initialize_control, NULL);
 
     rtems_interrupt_lock_release (&capture_lock_global, &lock_context);
   }
@@ -726,10 +728,11 @@ rtems_capture_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 *user RTEMS_UNUSED)
 {
   tcb->Capture.flags &= ~RTEMS_CAPTURE_TRACED;
+  return false;
 }
 
 /*
@@ -750,7 +753,7 @@ rtems_capture_flush (bool prime)
     return RTEMS_UNSATISFIED;
   }
 
-  rtems_iterate_over_all_threads (rtems_capture_flush_tcb);
+  rtems_iterate_over_all_threads (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 abfd4db..3dd9c57 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           *user RTEMS_UNUSED
 )
 {
   const Scheduler_Control *scheduler;
@@ -42,6 +43,8 @@ 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 +64,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_iterate_over_all_threads(CPU_usage_Per_thread_handler, NULL);
 }
diff --git a/cpukit/libmisc/cpuuse/cpuusagetop.c b/cpukit/libmisc/cpuuse/cpuusagetop.c
index aa2b74c..e5d8469 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,18 @@ print_time(rtems_cpu_usage_data*    data,
 /*
  * Count the number of tasks.
  */
-static void
-task_counter(Thread_Control *thrad, void* arg)
+static bool
+task_counter(Thread_Control *thrad, void* arg RTEMS_UNUSED)
 {
   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;
@@ -283,6 +247,8 @@ task_usage(Thread_Control* thread, void* arg)
     data->current_usage[j] = current;
     break;
   }
+
+  return false;
 }
 
 /*
@@ -318,7 +284,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);
+    rtems_iterate_over_all_threads(task_counter, data);
 
     tasks_size = sizeof(Thread_Control*) * (data->task_count + 1);
     usage_size = sizeof(Timestamp_Control) * (data->task_count + 1);
@@ -349,7 +315,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);
+    rtems_iterate_over_all_threads(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 a4b606a..8e61087 100644
--- a/cpukit/libmisc/stackchk/check.c
+++ b/cpukit/libmisc/stackchk/check.c
@@ -390,8 +390,9 @@ static inline void *Stack_check_find_high_water_mark(
  */
 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           *user RTEMS_UNUSED
 )
 {
   uint32_t        size, used;
@@ -466,7 +467,7 @@ static void Stack_check_Dump_threads_usage(
     rtems_printf( printer, "%8" PRId32 "\n", used );
   }
 
-
+  return false;
 }
 
 /*
@@ -503,11 +504,11 @@ void rtems_stack_checker_report_usage_with_plugin(
   );
 
   /* iterate over all threads and dump the usage */
-  rtems_iterate_over_all_threads( Stack_check_Dump_threads_usage );
+  rtems_iterate_over_all_threads( Stack_check_Dump_threads_usage, NULL );
 
   #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, NULL);
   #endif
 
   printer = NULL;
diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h
index 46c222f..4e32018 100644
--- a/cpukit/score/include/rtems/score/thread.h
+++ b/cpukit/score/include/rtems/score/thread.h
@@ -894,17 +894,29 @@ void *_Thread_Idle_body(
 );
 #endif
 
-/**  This defines the type for a method which operates on a single thread.
+/**
+ * @brief Thread vistor function.
+ * This defines the type for a method which operates on a single thread.  The
+ * second argument is passed in to the iterator call.
+ *
+ * @retval true Stop the iteration.
+ * @retval false Continue the iteration.
  */
-typedef void (*rtems_per_thread_routine)( Thread_Control * );
+  typedef bool (*rtems_per_thread_routine)( Thread_Control *, void * );
 
 /**
- *  @brief Iterates over all threads.
- *  This routine iterates over all threads regardless of API and
- *  invokes the specified routine.
+ * @brief Iterates over all threads.
+ * This routine iterates over all threads regardless of API and invokes the
+ * specified routine.  The iteration is protected by the object allocator
+ * mutex. Object creation and dynamic memory allocation are allowed in this
+ * context.
+ *
+ * @param routine The vistor function.
+ * @param user User data passed to the vistor function.
  */
 void rtems_iterate_over_all_threads(
-  rtems_per_thread_routine routine
+  rtems_per_thread_routine  routine,
+  void                     *user
 );
 
 /**
diff --git a/cpukit/score/src/iterateoverthreads.c b/cpukit/score/src/iterateoverthreads.c
index 8933352..857dffd 100644
--- a/cpukit/score/src/iterateoverthreads.c
+++ b/cpukit/score/src/iterateoverthreads.c
@@ -21,7 +21,7 @@
 #include <rtems/score/thread.h>
 #include <rtems/score/objectimpl.h>
 
-void rtems_iterate_over_all_threads(rtems_per_thread_routine routine)
+void rtems_iterate_over_all_threads(rtems_per_thread_routine routine, void *user)
 {
   uint32_t             i;
   uint32_t             api_index;
@@ -31,6 +31,8 @@ void rtems_iterate_over_all_threads(rtems_per_thread_routine routine)
   if ( !routine )
     return;
 
+  _Objects_Allocator_lock( );
+
   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 ] )
@@ -47,8 +49,11 @@ void rtems_iterate_over_all_threads(rtems_per_thread_routine routine)
       if ( !the_thread )
 	continue;
 
-      (*routine)(the_thread);
+      if ((*routine)(the_thread, user))
+        break;
     }
   }
 
+  _Objects_Allocator_unlock( );
+
 }
diff --git a/testsuites/sptests/sp41/init.c b/testsuites/sptests/sp41/init.c
index c484608..7a170ab 100644
--- a/testsuites/sptests/sp41/init.c
+++ b/testsuites/sptests/sp41/init.c
@@ -21,10 +21,12 @@ const char rtems_test_name[] = "SP 41";
 rtems_task Init(rtems_task_argument argument);
 void iterator(Thread_Control *thread);
 
-void iterator(
-  Thread_Control *thread
+bool iterator(
+  Thread_Control *thread,
+  void           *user
 )
 {
+  return false;
 }
 
 rtems_task Init(
@@ -40,7 +42,7 @@ rtems_task Init(
   _Objects_Information_table[ OBJECTS_CLASSIC_API ][ 1 ] = NULL;
 
   puts( "Init - rtems_iterate_over_all_threads" );
-  rtems_iterate_over_all_threads(iterator);
+  rtems_iterate_over_all_threads(iterator, NULL);
   _Objects_Information_table[ OBJECTS_CLASSIC_API ][ 1 ] = tmp;
 
   TEST_END();
-- 
2.4.6



More information about the devel mailing list