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 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel