spin_wait.h 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. // This file provides a macro ONLY for use in testing.
  5. // DO NOT USE IN PRODUCTION CODE. There are much better ways to wait.
  6. // This code is very helpful in testing multi-threaded code, without depending
  7. // on almost any primitives. This is especially helpful if you are testing
  8. // those primitive multi-threaded constructs.
  9. // We provide a simple one argument spin wait (for 1 second), and a generic
  10. // spin wait (for longer periods of time).
  11. #ifndef BASE_TEST_SPIN_WAIT_H_
  12. #define BASE_TEST_SPIN_WAIT_H_
  13. #include "base/threading/platform_thread.h"
  14. #include "base/time/time.h"
  15. // Provide a macro that will wait no longer than 1 second for an asynchronous
  16. // change is the value of an expression.
  17. // A typical use would be:
  18. //
  19. // SPIN_FOR_1_SECOND_OR_UNTIL_TRUE(0 == f(x));
  20. //
  21. // The expression will be evaluated repeatedly until it is true, or until
  22. // the time (1 second) expires.
  23. // Since tests generally have a 5 second watch dog timer, this spin loop is
  24. // typically used to get the padding needed on a given test platform to assure
  25. // that the test passes, even if load varies, and external events vary.
  26. #define SPIN_FOR_1_SECOND_OR_UNTIL_TRUE(expression) \
  27. SPIN_FOR_TIMEDELTA_OR_UNTIL_TRUE(base::TimeDelta::FromSeconds(1), \
  28. (expression))
  29. #define SPIN_FOR_TIMEDELTA_OR_UNTIL_TRUE(delta, expression) \
  30. do { \
  31. base::TimeTicks spin_wait_start = base::TimeTicks::Now(); \
  32. const base::TimeDelta kSpinWaitTimeout = delta; \
  33. while (!(expression)) { \
  34. if (kSpinWaitTimeout < base::TimeTicks::Now() - spin_wait_start) { \
  35. EXPECT_LE((base::TimeTicks::Now() - spin_wait_start).InMilliseconds(), \
  36. kSpinWaitTimeout.InMilliseconds()) \
  37. << "Timed out"; \
  38. break; \
  39. } \
  40. base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(50)); \
  41. } \
  42. } while (0)
  43. #endif // BASE_TEST_SPIN_WAIT_H_