[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