misc.cpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. /* Definitions for miscelaneous functions.
  2. This file is part of khipu.
  3. khipu is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU Lesser General Public License as published by
  5. the Free Software Foundation; either version 3 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU Lesser General Public License for more details.
  11. You should have received a copy of the GNU Lesser General Public License
  12. along with this program. If not, see <https://www.gnu.org/licenses/>. */
  13. #include <chrono>
  14. #include "interp.hpp"
  15. #include "thread.hpp"
  16. #include "xtime.hpp"
  17. KP_DECLS_BEGIN
  18. uint32_t upsize (uint32_t n)
  19. {
  20. if (n < 8)
  21. return (8);
  22. uint32_t ret = n;
  23. ret |= ret >> 1;
  24. ret |= ret >> 2;
  25. ret |= ret >> 4;
  26. ret |= ret >> 8;
  27. ret |= ret >> 16;
  28. return (++ret);
  29. }
  30. bool varobj::set_flag (uint32_t flg)
  31. {
  32. bool ret;
  33. if (singlethr_p ())
  34. {
  35. ret = (this->vo_full & flg) != flg;
  36. this->vo_full |= flg;
  37. }
  38. else
  39. ret = (atomic_or ((atomic_t *)&this->vo_full, flg) & flg) != flg;
  40. return (ret);
  41. }
  42. bool varobj::clr_flag (uint32_t flg)
  43. {
  44. bool ret;
  45. if (singlethr_p ())
  46. {
  47. ret = (this->vo_full & flg) != 0;
  48. this->vo_full &= ~flg;
  49. }
  50. else
  51. ret = (atomic_and ((atomic_t *)&this->vo_full, flg) & flg) != 0;
  52. return (ret);
  53. }
  54. bool varobj::cas_flag (uint32_t mask, uint32_t set)
  55. {
  56. if (singlethr_p ())
  57. {
  58. uintptr_t prev = this->vo_full;
  59. this->vo_full = (this->vo_full & ~mask) | set;
  60. return (prev == this->vo_full);
  61. }
  62. while (true)
  63. {
  64. atomic_t prev = this->vo_full;
  65. atomic_t nval = (prev & ~mask) | set;
  66. if (prev == nval)
  67. return (false);
  68. else if (atomic_cas_bool ((atomic_t *)&this->vo_full, prev, nval))
  69. return (true);
  70. atomic_spin_nop ();
  71. }
  72. }
  73. template <typename Clock>
  74. static double get_tstamp ()
  75. {
  76. auto now = Clock::now().time_since_epoch ();
  77. auto ns = std::chrono::duration_cast<std::chrono::nanoseconds> (now);
  78. return (ns.count () * 1e-9);
  79. }
  80. double monotonic_time ()
  81. {
  82. return (get_tstamp<std::chrono::steady_clock> ());
  83. }
  84. double real_time ()
  85. {
  86. return (get_tstamp<std::chrono::system_clock> ());
  87. }
  88. KP_DECLS_END