Skip to content

Commit

Permalink
kernel/system_info: Avoid malloc() in _user_get_cpu_info.
Browse files Browse the repository at this point in the history
This is called 15-30 times per second (15 by Pulse, 30 by ActivityMonitor),
so we want to keep it as low-profile as is possible.
  • Loading branch information
waddlesplash committed Jul 13, 2019
1 parent 6d336fd commit fa14652
Showing 1 changed file with 18 additions and 17 deletions.
35 changes: 18 additions & 17 deletions src/system/kernel/system_info.cpp
Expand Up @@ -500,12 +500,28 @@ get_cpu_info(uint32 firstCPU, uint32 cpuCount, cpu_info* info)


uint32 count = std::min(cpuCount, smp_get_num_cpus() - firstCPU); uint32 count = std::min(cpuCount, smp_get_num_cpus() - firstCPU);


memset(info, 0, sizeof(cpu_info) * count); // This function is called very often from userland by applications
// that display CPU usage information, so we want to keep this as
// optimized and touch as little as possible. Hence, no use of
// a temporary buffer.

if (IS_USER_ADDRESS(info)) {
if (user_memset(info, 0, sizeof(cpu_info) * count) != B_OK)
return B_BAD_ADDRESS;
set_ac();
} else {
memset(info, 0, sizeof(cpu_info) * count);
}

for (uint32 i = 0; i < count; i++) { for (uint32 i = 0; i < count; i++) {
info[i].active_time = cpu_get_active_time(firstCPU + i); info[i].active_time = cpu_get_active_time(firstCPU + i);
info[i].enabled = !gCPU[firstCPU + i].disabled; info[i].enabled = !gCPU[firstCPU + i].disabled;
} }


if (IS_USER_ADDRESS(info)) {
clear_ac();
}

return B_OK; return B_OK;
} }


Expand Down Expand Up @@ -561,23 +577,8 @@ _user_get_cpu_info(uint32 firstCPU, uint32 cpuCount, cpu_info* userInfo)
{ {
if (userInfo == NULL || !IS_USER_ADDRESS(userInfo)) if (userInfo == NULL || !IS_USER_ADDRESS(userInfo))
return B_BAD_ADDRESS; return B_BAD_ADDRESS;
if (firstCPU >= (uint32)smp_get_num_cpus())
return B_BAD_VALUE;
if (cpuCount == 0)
return B_OK;

uint32 count = std::min(cpuCount, smp_get_num_cpus() - firstCPU);

cpu_info* cpuInfos = new(std::nothrow) cpu_info[count];
if (cpuInfos == NULL)
return B_NO_MEMORY;
ArrayDeleter<cpu_info> _(cpuInfos);

status_t error = get_cpu_info(firstCPU, count, cpuInfos);
if (error != B_OK)
return error;


return user_memcpy(userInfo, cpuInfos, sizeof(cpu_info) * count); return get_cpu_info(firstCPU, cpuCount, userInfo);
} }




Expand Down

0 comments on commit fa14652

Please sign in to comment.