static int rtems_shell_main_malloc_info( int argc, char *argv[] ) { if ( argc == 2 ) { rtems_shell_print_unified_work_area_message(); if ( !strcmp( argv[1], "info" ) ) { region_information_block info; malloc_info( &info ); rtems_shell_print_heap_info( "free", &info.Free ); rtems_shell_print_heap_info( "used", &info.Used ); return 0; } else if ( !strcmp( argv[1], "stats" ) ) { malloc_report_statistics_with_plugin( stdout, (rtems_printk_plugin_t) fprintf ); return 0; } } fprintf( stderr, "%s: [info|stats]\n", argv[0] ); return -1; }
static void test_heap_info(void) { size_t s1, s2; void *p1; int sc; Heap_Information_block the_info; free_all_delayed_blocks(); s1 = malloc_free_space(); p1 = malloc( 512 ); s2 = malloc_free_space(); puts( "malloc_free_space - check malloc space drops after malloc" ); rtems_test_assert( s1 ); rtems_test_assert( s2 ); rtems_test_assert( s2 <= s1 ); do_free( p1 ); puts( "malloc_free_space - verify free space returns to previous value" ); s2 = malloc_free_space(); rtems_test_assert( s1 == s2 ); puts( "malloc_info - called with NULL\n" ); sc = malloc_info( NULL ); rtems_test_assert( sc == -1 ); puts( "malloc_info - check free space drops after malloc" ); sc = malloc_info( &the_info ); rtems_test_assert( sc == 0 ); s1 = the_info.Free.largest; p1 = malloc( 512 ); sc = malloc_info( &the_info ); rtems_test_assert( sc == 0 ); s2 = the_info.Free.largest; rtems_test_assert( s1 ); rtems_test_assert( s2 ); rtems_test_assert( s2 <= s1 ); do_free( p1 ); puts( "malloc_info - verify free space returns to previous value" ); sc = malloc_info( &the_info ); rtems_test_assert( sc == 0 ); rtems_test_assert( s1 == the_info.Free.largest ); }
static int do_test (void) { xpthread_barrier_init (&barrier, NULL, thread_count + 1); pthread_t threads[thread_count]; for (size_t i = 0; i < array_length (threads); ++i) threads[i] = xpthread_create (NULL, allocation_thread_function, NULL); xpthread_barrier_wait (&barrier); puts ("info: After allocation:"); malloc_info (0, stdout); xpthread_barrier_wait (&barrier); for (size_t i = 0; i < array_length (threads); ++i) xpthread_join (threads[i]); puts ("\ninfo: After deallocation:"); malloc_info (0, stdout); return 0; }
static std::string RPCMallocInfo() { char *ptr = nullptr; size_t size = 0; FILE *f = open_memstream(&ptr, &size); if (f) { malloc_info(0, f); fclose(f); if (ptr) { std::string rv(ptr, size); free(ptr); return rv; } } return ""; }
char * get_mem_info(void) { FILE *stream; char *buf; size_t len; int err = 0; stream = open_memstream(&buf, &len); if (stream == NULL) return NULL; err = malloc_info(0, stream); fclose(stream); if (err == -1) { free(buf); return NULL; } return buf; }
void heap_trace(struct mm_heap *heap, int size) { malloc_info(0, stdout); }
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); }