void *POSIX_Init( void *argument ) { char name[128]; char *ptr; rtems_status_code status; TEST_BEGIN(); ptr = rtems_object_get_name( pthread_self(), 128, name ); printf( "rtems_object_get_name returned (%s) for init thread\n", ptr ); /* Set my name to Justin */ puts( "Setting current thread name to Justin" ); status = rtems_object_set_name( pthread_self(), "Justin" ); directive_failed( status, "rtems_object_set_name" ); ptr = rtems_object_get_name( pthread_self(), 128, name ); printf( "rtems_object_get_name returned (%s) for init thread\n", ptr ); /* Set my name to Jordan */ puts( "Setting current thread name to Jordan" ); status = rtems_object_set_name( pthread_self(), "Jordan" ); directive_failed( status, "rtems_object_set_name" ); ptr = rtems_object_get_name( pthread_self(), 128, name ); printf( "rtems_object_get_name returned (%s) for init thread\n", ptr ); /* exercise the POSIX path through some routines */ printf( "rtems_object_api_minimum_class(OBJECTS_POSIX_API) returned %d\n", rtems_object_api_minimum_class(OBJECTS_POSIX_API) ); printf( "rtems_object_api_maximum_class(OBJECTS_POSIX_API) returned %d\n", rtems_object_api_maximum_class(OBJECTS_POSIX_API) ); printf( "rtems_object_get_api_name(POSIX_API) = %s\n", rtems_object_get_api_name(OBJECTS_POSIX_API) ); printf("rtems_object_get_api_class_name(POSIX_API, POSIX_KEYS) = %s\n", rtems_object_get_api_class_name( OBJECTS_POSIX_API, OBJECTS_POSIX_KEYS) ); TEST_END(); rtems_test_exit( 0 ); return NULL; }
rtems_task Test_task( rtems_task_argument unused ) { rtems_id tid; rtems_time_of_day time; uint32_t task_index; rtems_status_code status; int cpu_num; char name[5]; char *p; /* Get the task name */ p = rtems_object_get_name( RTEMS_SELF, 5, name ); rtems_test_assert( p != NULL ); status = rtems_task_ident( RTEMS_SELF, RTEMS_SEARCH_ALL_NODES, &tid ); task_index = task_number( tid ); for ( ; ; ) { /* Get the CPU Number */ cpu_num = bsp_smp_processor_id(); status = rtems_clock_get_tod( &time ); if ( time.second >= 35 ) { locked_printf( "*** END OF SMP08 TEST ***" ); rtems_test_exit( 0 ); } PrintTaskInfo( p, &time ); status = rtems_task_wake_after( task_index * 5 * rtems_clock_get_ticks_per_second() ); } }
rtems_task Test_task( rtems_task_argument unused ) { rtems_id tid; rtems_time_of_day time; uint32_t task_index; rtems_status_code status; char name[5]; char *p; /* Get the task name */ p = rtems_object_get_name( RTEMS_SELF, 5, name ); rtems_test_assert( p != NULL ); status = rtems_task_ident( RTEMS_SELF, RTEMS_SEARCH_ALL_NODES, &tid ); rtems_test_assert( status == RTEMS_SUCCESSFUL ); task_index = task_number( tid ); for ( ; ; ) { status = rtems_clock_get_tod( &time ); rtems_test_assert( status == RTEMS_SUCCESSFUL ); if ( time.second >= 35 ) { TEST_END(); rtems_test_exit( 0 ); } PrintTaskInfo( p, &time ); status = rtems_task_wake_after( task_index * 5 * rtems_clock_get_ticks_per_second() ); rtems_test_assert( status == RTEMS_SUCCESSFUL ); } }
rtems_task Test_task( rtems_task_argument task_index ) { uint32_t cpu_num; char name[5]; char *p; /* Get the task name */ p = rtems_object_get_name( RTEMS_SELF, 5, name ); rtems_test_assert( p != NULL ); /* Get the CPU Number */ cpu_num = rtems_smp_get_current_processor(); /* Print that the task is up and running. */ Loop(); locked_printf(" CPU %" PRIu32 " running Task %s\n", cpu_num, name); /* Set the flag that the task is up and running */ TaskRan[cpu_num] = true; /* Drop into a loop which will keep this task on * running on the cpu. */ while(1); }
rtems_task Wait_task( rtems_task_argument argument ) { char name[5]; char *p; bool allDone; int i; /* Get the task name */ p = rtems_object_get_name( RTEMS_SELF, 5, name ); rtems_test_assert( p != NULL ); /* Wait on the all tasks to run */ while (1) { allDone = true; for ( i=0; i<TASK_NUMS ; i++ ) { if (TaskRan[i] == false) allDone = false; } if (allDone) { puts( "\n\n*** END OF TEST spatomic07 ***\n" ); rtems_test_exit( 0 ); } } }
int rtems_monitor_dump_name(rtems_id id) { char name_buffer[18] = "????"; rtems_object_get_name( id, sizeof(name_buffer), name_buffer ); return fprintf( stdout, name_buffer ); }
rtems_task Test_task( rtems_task_argument argument ) { char name[5]; char *p; rtems_status_code status; /* Get the task name */ p = rtems_object_get_name( RTEMS_SELF, 5, name ); rtems_test_assert( p != NULL ); /* Print that the task is up and running. */ /* test relaxed barrier */ ATOMIC_CAS_NO_BARRIER(int, Int, argument, ATOMIC_RELAXED_BARRIER); ATOMIC_CAS_NO_BARRIER(long, Long, argument, ATOMIC_RELAXED_BARRIER); ATOMIC_CAS_NO_BARRIER(ptr, Pointer, argument, ATOMIC_RELAXED_BARRIER); ATOMIC_CAS_NO_BARRIER(32, Int32, argument, ATOMIC_RELAXED_BARRIER); /* test acquire barrier */ ATOMIC_CAS_NO_BARRIER(int, Int, argument, ATOMIC_ACQUIRE_BARRIER); ATOMIC_CAS_NO_BARRIER(long, Long, argument, ATOMIC_ACQUIRE_BARRIER); ATOMIC_CAS_NO_BARRIER(ptr, Pointer, argument, ATOMIC_ACQUIRE_BARRIER); ATOMIC_CAS_NO_BARRIER(32, Int32, argument, ATOMIC_ACQUIRE_BARRIER); /* test release barrier */ ATOMIC_CAS_NO_BARRIER(int, Int, argument, ATOMIC_RELEASE_BARRIER); ATOMIC_CAS_NO_BARRIER(long, Long, argument, ATOMIC_RELEASE_BARRIER); ATOMIC_CAS_NO_BARRIER(ptr, Pointer, argument, ATOMIC_RELEASE_BARRIER); ATOMIC_CAS_NO_BARRIER(32, Int32, argument, ATOMIC_RELEASE_BARRIER); /* Set the flag that the task is up and running */ TaskRan[argument] = true; status = rtems_task_delete( RTEMS_SELF ); directive_failed( status, "delete" ); }
rtems_task Test_task( rtems_task_argument argument ) { uint32_t cpu_num; char name[5]; char *p; /* Get the task name */ p = rtems_object_get_name( RTEMS_SELF, 5, name ); rtems_test_assert( p != NULL ); /* Get the CPU Number */ cpu_num = rtems_smp_get_current_processor(); /* Print that the task is up and running. */ /* test relaxed barrier */ ATOMIC_FETCH_ADD_NO_BARRIER(ulong, Ulong, unsigned long, cpu_num, ATOMIC_ORDER_RELAXED); ATOMIC_FETCH_ADD_NO_BARRIER(ptr, Pointer, uintptr_t, cpu_num, ATOMIC_ORDER_RELAXED); /* test acquire barrier */ ATOMIC_FETCH_ADD_NO_BARRIER(ulong, Ulong, unsigned long, cpu_num, ATOMIC_ORDER_ACQUIRE); ATOMIC_FETCH_ADD_NO_BARRIER(ptr, Pointer, uintptr_t, cpu_num, ATOMIC_ORDER_ACQUIRE); /* test release barrier */ ATOMIC_FETCH_ADD_NO_BARRIER(ulong, Ulong, unsigned long, cpu_num, ATOMIC_ORDER_RELEASE); ATOMIC_FETCH_ADD_NO_BARRIER(ptr, Pointer, uintptr_t, cpu_num, ATOMIC_ORDER_RELEASE); // ATOMIC_FETCH_ADD_NO_BARRIER(64, cpu_num); /* Set the flag that the task is up and running */ TaskRan[cpu_num] = true; /* Drop into a loop which will keep this task on * running on the cpu. */ while(1); }
static void rtems_bsd_dump_thread(Thread_Control *thread) { const struct thread *td = rtems_bsd_get_thread(thread); if (td != NULL) { char buf[5]; const char *name = td->td_name; if (name == NULL || name[0] == '\0') { rtems_object_get_name(thread->Object.id, sizeof(buf), &buf[0]); name = &buf[0]; } fprintf( stdout, " 0x%08" PRIx32 " | %8" PRIu32 " | %s\n", thread->Object.id, _Thread_Get_priority(thread), name ); } }
rtems_task Test_task( rtems_task_argument do_exit ) { int cpu_num; char name[5]; char *p; p = rtems_object_get_name( RTEMS_SELF, 5, name ); rtems_test_assert( p != NULL ); cpu_num = bsp_smp_processor_id(); locked_printf(" CPU %d running Task %s\n", cpu_num, name); Ran = true; if ( do_exit ) { locked_printf( "*** END OF TEST SMP06 ***\n" ); rtems_test_exit(0); } while(1) ; }
rtems_task Test_task( rtems_task_argument argument ) { uint32_t cpu_num; rtems_status_code sc; char name[5]; char *p; /* Get the task name */ p = rtems_object_get_name( RTEMS_SELF, 5, name ); rtems_test_assert( p != NULL ); /* Get the CPU Number */ cpu_num = rtems_get_current_processor(); /* Print that the task is up and running. */ locked_printf(" CPU %" PRIu32 " runnng Task %s and blocking\n", cpu_num, name); sc = rtems_semaphore_obtain( Semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT ); directive_failed( sc,"obtain in test task"); if ( !TSRFired ) locked_printf( "*** ERROR TSR DID NOT FIRE BUT TEST TASK AWAKE***" ); TaskRan = true; /* Print that the task is up and running. */ locked_printf( " CPU %" PRIu32 " running Task %s after semaphore release\n", cpu_num, name ); /* FIXME: Task deletion currently not supported */ (void) rtems_task_suspend( RTEMS_SELF ); }
void rtems_rate_monotonic_report_statistics_with_plugin( void *context, rtems_printk_plugin_t print ) { rtems_status_code status; rtems_id id; rtems_rate_monotonic_period_statistics the_stats; rtems_rate_monotonic_period_status the_status; char name[5]; if ( !print ) return; (*print)( context, "Period information by period\n" ); (*print)( context, "--- CPU times are in seconds ---\n" ); (*print)( context, "--- Wall times are in seconds ---\n" ); /* Layout by columns -- in memory of Hollerith :) 1234567890123456789012345678901234567890123456789012345678901234567890123456789\ ID OWNER COUNT MISSED X ididididid NNNN ccccc mmmmmm X Uncomment the following if you are tinkering with the formatting. Be sure to test the various cases. (*print)( context,"\ 1234567890123456789012345678901234567890123456789012345678901234567890123456789\ \n"); */ (*print)( context, " ID OWNER COUNT MISSED " " CPU TIME WALL TIME\n" " " " MIN/MAX/AVG MIN/MAX/AVG\n" ); /* * Cycle through all possible ids and try to report on each one. If it * is a period that is inactive, we just get an error back. No big deal. */ for ( id=_Rate_monotonic_Information.minimum_id ; id <= _Rate_monotonic_Information.maximum_id ; id++ ) { status = rtems_rate_monotonic_get_statistics( id, &the_stats ); if ( status != RTEMS_SUCCESSFUL ) continue; /* If the above passed, so should this but check it anyway */ #if defined(RTEMS_DEBUG) status = rtems_rate_monotonic_get_status( id, &the_status ); if ( status != RTEMS_SUCCESSFUL ) continue; #else (void) rtems_rate_monotonic_get_status( id, &the_status ); #endif rtems_object_get_name( the_status.owner, sizeof(name), name ); /* * Print part of report line that is not dependent on granularity */ (*print)( context, "0x%08" PRIx32 " %4s %5" PRId32 " %6" PRId32 " ", id, name, the_stats.count, the_stats.missed_count ); /* * If the count is zero, don't print statistics */ if (the_stats.count == 0) { (*print)( context, "\n" ); continue; } /* * print CPU Usage part of statistics */ { struct timespec cpu_average; struct timespec *min_cpu = &the_stats.min_cpu_time; struct timespec *max_cpu = &the_stats.max_cpu_time; struct timespec *total_cpu = &the_stats.total_cpu_time; _Timespec_Divide_by_integer( total_cpu, the_stats.count, &cpu_average ); (*print)( context, "%" PRId32 "." NANOSECONDS_FMT "/" /* min cpu time */ "%" PRId32 "." NANOSECONDS_FMT "/" /* max cpu time */ "%" PRId32 "." NANOSECONDS_FMT " ", /* avg cpu time */ _Timespec_Get_seconds( min_cpu ), _Timespec_Get_nanoseconds( min_cpu ) / NANOSECONDS_DIVIDER, _Timespec_Get_seconds( max_cpu ), _Timespec_Get_nanoseconds( max_cpu ) / NANOSECONDS_DIVIDER, _Timespec_Get_seconds( &cpu_average ), _Timespec_Get_nanoseconds( &cpu_average ) / NANOSECONDS_DIVIDER ); } /* * print wall time part of statistics */ { struct timespec wall_average; struct timespec *min_wall = &the_stats.min_wall_time; struct timespec *max_wall = &the_stats.max_wall_time; struct timespec *total_wall = &the_stats.total_wall_time; _Timespec_Divide_by_integer(total_wall, the_stats.count, &wall_average); (*print)( context, "%" PRId32 "." NANOSECONDS_FMT "/" /* min wall time */ "%" PRId32 "." NANOSECONDS_FMT "/" /* max wall time */ "%" PRId32 "." NANOSECONDS_FMT "\n", /* avg wall time */ _Timespec_Get_seconds( min_wall ), _Timespec_Get_nanoseconds( min_wall ) / NANOSECONDS_DIVIDER, _Timespec_Get_seconds( max_wall ), _Timespec_Get_nanoseconds( max_wall ) / NANOSECONDS_DIVIDER, _Timespec_Get_seconds( &wall_average ), _Timespec_Get_nanoseconds( &wall_average ) / NANOSECONDS_DIVIDER ); } } }
/* Get thread information, return 0 if thread does not exist and 1 otherwise */ static int rtems_gdb_stub_get_thread_info( int gdb_index, struct rtems_gdb_stub_thread_info *info ) { int first = 1; size_t api_index; ASSERT(info != NULL); if (gdb_index <= 0) { return 0; } if (_System_state_Get() != SYSTEM_STATE_UP || gdb_index == 1) { /* We have one thread let us use value which will never happen for real thread */ strcpy(info->display, "idle thread"); strcpy(info->name, "IDLE"); info->more_display[0] = 0; /* Nothing */ return 1; } for ( api_index = 1; api_index <= OBJECTS_APIS_LAST; ++api_index ) { if (_Objects_Information_table[api_index] != NULL) { const Objects_Information *obj_info = _Objects_Information_table[api_index][1]; Objects_Id min_id = obj_info->minimum_id; Objects_Id max_id = obj_info->maximum_id; int last = first + (int) (max_id - min_id); if (gdb_index <= last) { Thread_Control *th = (Thread_Control *) obj_info->local_table[gdb_index - first + 1]; if (th != NULL) { char tmp_buf[9]; strcpy(info->display, "task: control at 0x"); tmp_buf[0] = gdb_hexchars[(((int)th) >> 28) & 0xf]; tmp_buf[1] = gdb_hexchars[(((int)th) >> 24) & 0xf]; tmp_buf[2] = gdb_hexchars[(((int)th) >> 20) & 0xf]; tmp_buf[3] = gdb_hexchars[(((int)th) >> 16) & 0xf]; tmp_buf[4] = gdb_hexchars[(((int)th) >> 12) & 0xf]; tmp_buf[5] = gdb_hexchars[(((int)th) >> 8) & 0xf]; tmp_buf[6] = gdb_hexchars[(((int)th) >> 4) & 0xf]; tmp_buf[7] = gdb_hexchars[((int)th) & 0xf]; tmp_buf[8] = 0; strcat(info->display, tmp_buf); rtems_object_get_name( th->Object.id, 5, info->name ); info->more_display[0] = 0; /* Nothing */ return 1; } else { /* Thread does not exist */ return 0; } }
/* * rtems_cpu_usage_report */ void rtems_cpu_usage_report_with_plugin( void *context, rtems_printk_plugin_t print ) { uint32_t i; uint32_t api_index; Thread_Control *the_thread; Objects_Information *information; char name[13]; uint32_t ival, fval; #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ Timestamp_Control uptime, total, ran, uptime_at_last_reset; uint32_t seconds, nanoseconds; #else uint32_t total_units = 0; #endif if ( !print ) return; /* * When not using nanosecond CPU usage resolution, we have to count * the number of "ticks" we gave credit for to give the user a rough * guideline as to what each number means proportionally. */ #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ _Timestamp_Set_to_zero( &total ); uptime_at_last_reset = CPU_usage_Uptime_at_last_reset; #else 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 ) total_units += the_thread->cpu_time_used; } } } #endif (*print)( context, "-------------------------------------------------------------------------------\n" " CPU USAGE BY THREAD\n" "------------+----------------------------------------+---------------+---------\n" #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ " ID | NAME | SECONDS | PERCENT\n" #else " ID | NAME | TICKS | PERCENT\n" #endif "------------+----------------------------------------+---------------+---------\n" ); 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 ) continue; rtems_object_get_name( the_thread->Object.id, sizeof(name), name ); (*print)( context, " 0x%08" PRIx32 " | %-38s |", the_thread->Object.id, name ); #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ { Timestamp_Control last; /* * If this is the currently executing thread, account for time * since the last context switch. */ ran = the_thread->cpu_time_used; if ( is_executing_on_a_core( the_thread, &last ) ) { Timestamp_Control used; _TOD_Get_uptime( &uptime ); _Timestamp_Subtract( &last, &uptime, &used ); _Timestamp_Add_to( &ran, &used ); } else { _TOD_Get_uptime( &uptime ); } _Timestamp_Subtract( &uptime_at_last_reset, &uptime, &total ); _Timestamp_Divide( &ran, &total, &ival, &fval ); /* * Print the information */ seconds = _Timestamp_Get_seconds( &ran ); nanoseconds = _Timestamp_Get_nanoseconds( &ran ) / TOD_NANOSECONDS_PER_MICROSECOND; (*print)( context, "%7" PRIu32 ".%06" PRIu32 " |%4" PRIu32 ".%03" PRIu32 "\n", seconds, nanoseconds, ival, fval ); } #else if (total_units) { uint64_t ival_64; ival_64 = the_thread->cpu_time_used; ival_64 *= 100000; ival = ival_64 / total_units; } else { ival = 0; } fval = ival % 1000; ival /= 1000; (*print)( context, "%14" PRIu32 " |%4" PRIu32 ".%03" PRIu32 "\n", the_thread->cpu_time_used, ival, fval ); #endif } } } #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ seconds = _Timestamp_Get_seconds( &total ); nanoseconds = _Timestamp_Get_nanoseconds( &total ) / TOD_NANOSECONDS_PER_MICROSECOND; (*print)( context, "------------+----------------------------------------+---------------+---------\n" " TIME SINCE LAST CPU USAGE RESET IN SECONDS: %7" PRIu32 ".%06" PRIu32 "\n" "-------------------------------------------------------------------------------\n", seconds, nanoseconds ); #else (*print)( context, "------------+----------------------------------------+---------------+---------\n" " TICKS SINCE LAST SYSTEM RESET: %14" PRIu32 "\n" " TOTAL UNITS: %14" PRIu32 "\n" "-------------------------------------------------------------------------------\n", _Watchdog_Ticks_since_boot - CPU_usage_Ticks_at_last_reset, total_units ); #endif }
static void rtems_cpuusage_top_thread (rtems_task_argument arg) { rtems_cpu_usage_data* data = (rtems_cpu_usage_data*) arg; char name[13]; int i; Heap_Information_block wksp; uint32_t ival, fval; int task_count; rtems_event_set out; rtems_status_code sc; bool first_time = true; data->thread_active = true; _TOD_Get_uptime(&data->last_uptime); CPU_usage_Set_to_zero(&data->zero); while (data->thread_run) { Timestamp_Control uptime_at_last_reset = CPU_usage_Uptime_at_last_reset; size_t tasks_size; size_t usage_size; Timestamp_Control load; data->task_count = 0; rtems_iterate_over_all_threads_2(task_counter, data); tasks_size = sizeof(Thread_Control*) * (data->task_count + 1); usage_size = sizeof(Timestamp_Control) * (data->task_count + 1); if (data->task_count > data->task_size) { data->tasks = realloc(data->tasks, tasks_size); data->usage = realloc(data->usage, usage_size); data->current_usage = realloc(data->current_usage, usage_size); if ((data->tasks == NULL) || (data->usage == NULL) || (data->current_usage == NULL)) { rtems_printf(data->printer, "top worker: error: no memory\n"); data->thread_run = false; break; } } memset(data->tasks, 0, tasks_size); memset(data->usage, 0, usage_size); memset(data->current_usage, 0, usage_size); _Timestamp_Set_to_zero(&data->total); _Timestamp_Set_to_zero(&data->current); data->stack_size = 0; _TOD_Get_uptime(&data->uptime); _Timestamp_Subtract(&uptime_at_last_reset, &data->uptime, &data->uptime); _Timestamp_Subtract(&data->last_uptime, &data->uptime, &data->period); data->last_uptime = data->uptime; rtems_iterate_over_all_threads_2(task_usage, data); if (data->task_count > data->task_size) { data->last_tasks = realloc(data->last_tasks, tasks_size); data->last_usage = realloc(data->last_usage, usage_size); if ((data->last_tasks == NULL) || (data->last_usage == NULL)) { rtems_printf(data->printer, "top worker: error: no memory\n"); data->thread_run = false; break; } data->task_size = data->task_count; } memcpy(data->last_tasks, data->tasks, tasks_size); memcpy(data->last_usage, data->usage, usage_size); data->last_task_count = data->task_count; /* * We need to loop again to get suitable current usage values as we need a * last sample to work. */ if (first_time) { rtems_task_wake_after(RTEMS_MILLISECONDS_TO_TICKS(500)); first_time = false; continue; } _Protected_heap_Get_information(&_Workspace_Area, &wksp); if (data->single_page) rtems_printf(data->printer, "\x1b[H\x1b[J" " ENTER:Exit SPACE:Refresh" " S:Scroll A:All <>:Order +/-:Lines\n"); rtems_printf(data->printer, "\n"); /* * Uptime and period of this sample. */ rtems_printf(data->printer, "Uptime: "); print_time(data, &data->uptime, 20); rtems_printf(data->printer, " Period: "); print_time(data, &data->period, 20); /* * Task count, load and idle levels. */ rtems_printf(data->printer, "\nTasks: %4i ", data->task_count); _Timestamp_Subtract(&data->idle, &data->total, &load); _Timestamp_Divide(&load, &data->uptime, &ival, &fval); rtems_printf(data->printer, "Load Average: %4" PRIu32 ".%03" PRIu32 "%%", ival, fval); _Timestamp_Subtract(&data->current_idle, &data->current, &load); _Timestamp_Divide(&load, &data->period, &ival, &fval); rtems_printf(data->printer, " Load: %4" PRIu32 ".%03" PRIu32 "%%", ival, fval); _Timestamp_Divide(&data->current_idle, &data->period, &ival, &fval); rtems_printf(data->printer, " Idle: %4" PRIu32 ".%03" PRIu32 "%%", ival, fval); /* * Memory usage. */ if (rtems_configuration_get_unified_work_area()) { rtems_printf(data->printer, "\nMem: "); print_memsize(data, wksp.Free.total, "free"); print_memsize(data, wksp.Used.total, "used"); } else { region_information_block libc_heap; malloc_info(&libc_heap); rtems_printf(data->printer, "\nMem: Wksp: "); print_memsize(data, wksp.Free.total, "free"); print_memsize(data, wksp.Used.total, "used Heap: "); print_memsize(data, libc_heap.Free.total, "free"); print_memsize(data, libc_heap.Used.total, "used"); } print_memsize(data, data->stack_size, "stack\n"); rtems_printf(data->printer, "\n" " ID | NAME | RPRI | CPRI | TIME | TOTAL | CURRENT\n" "-%s---------+---------------------+-%s-----%s-----+---------------------+-%s------+--%s----\n", data->sort_order == RTEMS_TOP_SORT_ID ? "^^" : "--", data->sort_order == RTEMS_TOP_SORT_REAL_PRI ? "^^" : "--", data->sort_order == RTEMS_TOP_SORT_CURRENT_PRI ? "^^" : "--", data->sort_order == RTEMS_TOP_SORT_TOTAL ? "^^" : "--", data->sort_order == RTEMS_TOP_SORT_CURRENT ? "^^" : "--" ); task_count = 0; for (i = 0; i < data->task_count; i++) { Thread_Control* thread = data->tasks[i]; Timestamp_Control usage; Timestamp_Control current_usage; if (thread == NULL) break; if (data->single_page && (data->show != 0) && (i >= data->show)) break; /* * We need to count the number displayed to clear the remainder of the * the display. */ ++task_count; /* * If the API os POSIX print the entry point. */ rtems_object_get_name(thread->Object.id, sizeof(name), name); if (name[0] == '\0') snprintf(name, sizeof(name) - 1, "(%p)", thread->Start.Entry.Kinds.Numeric.entry); rtems_printf(data->printer, " 0x%08" PRIx32 " | %-19s | %3" PRId64 " | %3" PRId64 " | ", thread->Object.id, name, thread->Real_priority.priority, _Thread_Get_priority(thread)); usage = data->usage[i]; current_usage = data->current_usage[i]; /* * Print the information */ print_time(data, &usage, 19); _Timestamp_Divide(&usage, &data->total, &ival, &fval); rtems_printf(data->printer, " |%4" PRIu32 ".%03" PRIu32, ival, fval); _Timestamp_Divide(¤t_usage, &data->period, &ival, &fval); rtems_printf(data->printer, " |%4" PRIu32 ".%03" PRIu32 "\n", ival, fval); } if (data->single_page && (data->show != 0) && (task_count < data->show)) { i = data->show - task_count; while (i > 0) { rtems_printf(data->printer, "\x1b[K\n"); i--; } } sc = rtems_event_receive(RTEMS_EVENT_1, RTEMS_EVENT_ANY, RTEMS_MILLISECONDS_TO_TICKS (data->poll_rate_usecs), &out); if ((sc != RTEMS_SUCCESSFUL) && (sc != RTEMS_TIMEOUT)) { rtems_printf(data->printer, "error: event receive: %s\n", rtems_status_text(sc)); break; } } free(data->tasks); free(data->last_tasks); free(data->last_usage); free(data->current_usage); data->thread_active = false; rtems_task_delete (RTEMS_SELF); }