time-utils.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. #include <stdlib.h>
  2. #include <string.h>
  3. #include <sys/time.h>
  4. #include <linux/time64.h>
  5. #include <time.h>
  6. #include <errno.h>
  7. #include <inttypes.h>
  8. #include "perf.h"
  9. #include "debug.h"
  10. #include "time-utils.h"
  11. int parse_nsec_time(const char *str, u64 *ptime)
  12. {
  13. u64 time_sec, time_nsec;
  14. char *end;
  15. time_sec = strtoul(str, &end, 10);
  16. if (*end != '.' && *end != '\0')
  17. return -1;
  18. if (*end == '.') {
  19. int i;
  20. char nsec_buf[10];
  21. if (strlen(++end) > 9)
  22. return -1;
  23. strncpy(nsec_buf, end, 9);
  24. nsec_buf[9] = '\0';
  25. /* make it nsec precision */
  26. for (i = strlen(nsec_buf); i < 9; i++)
  27. nsec_buf[i] = '0';
  28. time_nsec = strtoul(nsec_buf, &end, 10);
  29. if (*end != '\0')
  30. return -1;
  31. } else
  32. time_nsec = 0;
  33. *ptime = time_sec * NSEC_PER_SEC + time_nsec;
  34. return 0;
  35. }
  36. static int parse_timestr_sec_nsec(struct perf_time_interval *ptime,
  37. char *start_str, char *end_str)
  38. {
  39. if (start_str && (*start_str != '\0') &&
  40. (parse_nsec_time(start_str, &ptime->start) != 0)) {
  41. return -1;
  42. }
  43. if (end_str && (*end_str != '\0') &&
  44. (parse_nsec_time(end_str, &ptime->end) != 0)) {
  45. return -1;
  46. }
  47. return 0;
  48. }
  49. int perf_time__parse_str(struct perf_time_interval *ptime, const char *ostr)
  50. {
  51. char *start_str, *end_str;
  52. char *d, *str;
  53. int rc = 0;
  54. if (ostr == NULL || *ostr == '\0')
  55. return 0;
  56. /* copy original string because we need to modify it */
  57. str = strdup(ostr);
  58. if (str == NULL)
  59. return -ENOMEM;
  60. ptime->start = 0;
  61. ptime->end = 0;
  62. /* str has the format: <start>,<stop>
  63. * variations: <start>,
  64. * ,<stop>
  65. * ,
  66. */
  67. start_str = str;
  68. d = strchr(start_str, ',');
  69. if (d) {
  70. *d = '\0';
  71. ++d;
  72. }
  73. end_str = d;
  74. rc = parse_timestr_sec_nsec(ptime, start_str, end_str);
  75. free(str);
  76. /* make sure end time is after start time if it was given */
  77. if (rc == 0 && ptime->end && ptime->end < ptime->start)
  78. return -EINVAL;
  79. pr_debug("start time %" PRIu64 ", ", ptime->start);
  80. pr_debug("end time %" PRIu64 "\n", ptime->end);
  81. return rc;
  82. }
  83. bool perf_time__skip_sample(struct perf_time_interval *ptime, u64 timestamp)
  84. {
  85. /* if time is not set don't drop sample */
  86. if (timestamp == 0)
  87. return false;
  88. /* otherwise compare sample time to time window */
  89. if ((ptime->start && timestamp < ptime->start) ||
  90. (ptime->end && timestamp > ptime->end)) {
  91. return true;
  92. }
  93. return false;
  94. }