SliceBudget.h 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  2. * vim: set ts=8 sts=4 et sw=4 tw=99:
  3. * This Source Code Form is subject to the terms of the Mozilla Public
  4. * License, v. 2.0. If a copy of the MPL was not distributed with this
  5. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  6. #ifndef js_SliceBudget_h
  7. #define js_SliceBudget_h
  8. #include <stdint.h>
  9. namespace js {
  10. struct JS_PUBLIC_API(TimeBudget)
  11. {
  12. int64_t budget;
  13. explicit TimeBudget(int64_t milliseconds) { budget = milliseconds; }
  14. };
  15. struct JS_PUBLIC_API(WorkBudget)
  16. {
  17. int64_t budget;
  18. explicit WorkBudget(int64_t work) { budget = work; }
  19. };
  20. /*
  21. * This class records how much work has been done in a given collection slice,
  22. * so that we can return before pausing for too long. Some slices are allowed
  23. * to run for unlimited time, and others are bounded. To reduce the number of
  24. * gettimeofday calls, we only check the time every 1000 operations.
  25. */
  26. class JS_PUBLIC_API(SliceBudget)
  27. {
  28. static const int64_t unlimitedDeadline = INT64_MAX;
  29. static const intptr_t unlimitedStartCounter = INTPTR_MAX;
  30. bool checkOverBudget();
  31. SliceBudget();
  32. public:
  33. // Memory of the originally requested budget. If isUnlimited, neither of
  34. // these are in use. If deadline==0, then workBudget is valid. Otherwise
  35. // timeBudget is valid.
  36. TimeBudget timeBudget;
  37. WorkBudget workBudget;
  38. int64_t deadline; /* in microseconds */
  39. intptr_t counter;
  40. static const intptr_t CounterReset = 1000;
  41. static const int64_t UnlimitedTimeBudget = -1;
  42. static const int64_t UnlimitedWorkBudget = -1;
  43. /* Use to create an unlimited budget. */
  44. static SliceBudget unlimited() { return SliceBudget(); }
  45. /* Instantiate as SliceBudget(TimeBudget(n)). */
  46. explicit SliceBudget(TimeBudget time);
  47. /* Instantiate as SliceBudget(WorkBudget(n)). */
  48. explicit SliceBudget(WorkBudget work);
  49. void makeUnlimited() {
  50. deadline = unlimitedDeadline;
  51. counter = unlimitedStartCounter;
  52. }
  53. void step(intptr_t amt = 1) {
  54. counter -= amt;
  55. }
  56. bool isOverBudget() {
  57. if (counter > 0)
  58. return false;
  59. return checkOverBudget();
  60. }
  61. bool isWorkBudget() const { return deadline == 0; }
  62. bool isTimeBudget() const { return deadline > 0 && !isUnlimited(); }
  63. bool isUnlimited() const { return deadline == unlimitedDeadline; }
  64. int describe(char* buffer, size_t maxlen) const;
  65. };
  66. } // namespace js
  67. #endif /* js_SliceBudget_h */