Question

I am using the following code to get CPU load on iOS and Cocoa (Mach).

The strange thing is: if I call this code at regular intervals, say 30 times per second, available memory shrinks progressively and eventually the program crashes.

Profiling the program with Instruments, I see neither leaks, nor new memory allocation (the leaks diagram is empty and the allocation diagram is flat). Still, available physical memory keeps going down until the program crashes (it takes at least 40 minutes on an 256MB iPod, so it is not a big memory occupation).

What I suspect is that this code uses some kernel resource and does not release it correctly.

Is anyone able to explain this behaviour?

#include "cpu_usage.h"
#import <mach/mach.h>

float cpu_usage()
{
kern_return_t kr;
task_info_data_t tinfo;
mach_msg_type_number_t task_info_count;

task_info_count = TASK_INFO_MAX;
kr = task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)tinfo, &task_info_count);
if (kr != KERN_SUCCESS) {
    return -1;
}

thread_array_t         thread_list;
mach_msg_type_number_t thread_count;

thread_info_data_t     thinfo;
mach_msg_type_number_t thread_info_count;

thread_basic_info_t basic_info_th;

kr = task_threads(mach_task_self(), &thread_list, &thread_count);
if (kr != KERN_SUCCESS) {
    return -1;
}

long tot_sec = 0;
long tot_usec = 0;
float tot_cpu = 0;
int j;

for (j = 0; j < thread_count; j++)
{
    thread_info_count = THREAD_INFO_MAX;
    kr = thread_info(thread_list[j], THREAD_BASIC_INFO,
                     (thread_info_t)thinfo, &thread_info_count);
    if (kr != KERN_SUCCESS) {
        return -1;
    }

    basic_info_th = (thread_basic_info_t)thinfo;

    if (!(basic_info_th->flags & TH_FLAGS_IDLE)) {
        tot_sec = tot_sec + basic_info_th->user_time.seconds + basic_info_th->system_time.seconds;
        tot_usec = tot_usec + basic_info_th->system_time.microseconds + basic_info_th->system_time.microseconds;
        tot_cpu = tot_cpu + basic_info_th->cpu_usage / (float)TH_USAGE_SCALE * 100.0;
    }

}

return tot_cpu;
}
Was it helpful?

Solution

From the answer to this question iOS - Get CPU usage from application it can be seen that the memory allocated by

kr = task_threads(mach_task_self(), &thread_list, &thread_count);

must be released using

kr = vm_deallocate(mach_task_self(), (vm_offset_t)thread_list,
              thread_count * sizeof(thread_t));
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top