[FIXED] Getting incorrect Android.Systems.OsConstants values in .NET

Issue

I’m working on adding CPU monitoring to the Android portion of my Xamarin Forms app. I’m following the instructions found on this page, and currently have the following code written:

var self = new Java.IO.RandomAccessFile("/proc/self/stat", "r");
string[] info = self.ReadLine().Split(" ");

int clockSpeedHz = Android.Systems.OsConstants.ScClkTck;
int numCores = Android.Systems.OsConstants.ScNprocessorsConf;

double uptimeSec = SystemClock.ElapsedRealtime() / 1000.0;
long startTime = long.Parse(info[21]);

double cpuTimeSeconds = (long.Parse(info[13]) + long.Parse(info[14]) + long.Parse(info[15]) + long.Parse(info[16])) / (double)clockSpeedHz;
double processTimeSeconds = uptimeSec - (startTime / clockSpeedHz);
double avgUsagePercent = (100 * cpuTimeSeconds / processTimeSeconds) / numCores;

return avgUsagePercent;

After running this, the avgUsagePercent value doesn’t make sense (ex. average CPU usage is (-2*10^-8)%). Looking at the numbers, it seems like the issue is with the calls to Android.Systems.OsConstants. According to those values, my CPU has 96 cores, with a clock speed of 6 Hz. Setting those numbers to the expected values of my device (8 cores, 100 Hz) provides much more realistic values (2-10% CPU usage). I can’t rely on these numbers, however, as this app will be loaded onto different devices that might not have these values.

Does anyone know what the correct way to get Android.Systems.OsConstants values is? Taking a look at other constants in this namespace, it seems like these might just be indices in a list, since they’re all unique and roughly follow numerical order. I’m wondering if the .NET implementation of this namespace requires some function to convert the index to a value, and I’m just not aware of it. Otherwise if there’s a different implementation to access these values, I’m open to using those methods as well.

Solution

Those are constants that are used in sysconf to return the actual values of the device’s hardware (see Linux man page if you need to review sysconf features):

Incorrect:

int numCores = Android.Systems.OsConstants.ScNprocessorsConf;

Correct:

long numCores = Android.Systems.Os.Sysconf(Android.Systems.OsConstants.ScNprocessorsConf)

Answered By – SushiHangover

Answer Checked By – David Goodson (Easybugfix Volunteer)

Leave a Reply

(*) Required, Your email will not be published