bogomips.c 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. #include "api.h"
  2. #include "bogomips.h"
  3. /* This version is too dumb to be shared by the whole repository and should be removed once we get
  4. * a proper stdlib (like musl). */
  5. static double proc_cpuinfo_atod(const char* s) {
  6. double ret = 0.0;
  7. char* end = NULL;
  8. double base, fractional;
  9. base = strtol(s, &end, 10);
  10. if (*end == '.') {
  11. s = end + 1;
  12. fractional = strtol(s, &end, 10);
  13. while (s != end) {
  14. fractional /= 10.0;
  15. s++;
  16. }
  17. ret = base + fractional;
  18. }
  19. return ret;
  20. }
  21. double get_bogomips_from_cpuinfo_buf(const char* buf, size_t size) {
  22. /* We could use strstr if graphene had one. */
  23. /* Each prefix of the word "bogomips" occurs only once in the whole word, hence this works. */
  24. const char* const word = "bogomips";
  25. const size_t word_size = strlen(word);
  26. size_t i = 0,
  27. j = 0;
  28. if (word_size > size) {
  29. return 0.0;
  30. }
  31. while (i < size - word_size && buf[i]) {
  32. j = 0;
  33. while (j < word_size && buf[i + j] == word[j]) {
  34. j++;
  35. }
  36. if (j) {
  37. i += j;
  38. } else {
  39. i += 1;
  40. }
  41. if (j == word_size) {
  42. /* buf is null-terminated, so no need to check size. word does not contain neither
  43. * spaces nor tabs, hence we can forward global index `i`, even if we do not return
  44. * here. */
  45. while (buf[i] == ' ' || buf[i] == '\t') {
  46. i++;
  47. }
  48. if (buf[i] == ':') {
  49. return proc_cpuinfo_atod(&buf[i + 1]);
  50. }
  51. }
  52. }
  53. return 0.0;
  54. }
  55. double sanitize_bogomips_value(double v) {
  56. if (!__builtin_isnormal(v) || v < 0.0) {
  57. return 0.0;
  58. }
  59. return v;
  60. }