compat_threads.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /* Copyright (c) 2003-2004, Roger Dingledine
  2. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
  3. * Copyright (c) 2007-2019, The Tor Project, Inc. */
  4. /* See LICENSE for licensing information */
  5. /**
  6. * \file compat_threads.c
  7. *
  8. * \brief Cross-platform threading and inter-thread communication logic.
  9. * (Platform-specific parts are written in the other compat_*threads
  10. * modules.)
  11. */
  12. #include "orconfig.h"
  13. #include <stdlib.h>
  14. #include "lib/thread/threads.h"
  15. #include "lib/log/log.h"
  16. #include "lib/log/util_bug.h"
  17. #include <string.h>
  18. /** Allocate and return a new condition variable. */
  19. tor_cond_t *
  20. tor_cond_new(void)
  21. {
  22. tor_cond_t *cond = tor_malloc(sizeof(tor_cond_t));
  23. if (BUG(tor_cond_init(cond)<0))
  24. tor_free(cond); // LCOV_EXCL_LINE
  25. return cond;
  26. }
  27. /** Free all storage held in <b>c</b>. */
  28. void
  29. tor_cond_free_(tor_cond_t *c)
  30. {
  31. if (!c)
  32. return;
  33. tor_cond_uninit(c);
  34. tor_free(c);
  35. }
  36. /** Identity of the "main" thread */
  37. static unsigned long main_thread_id = -1;
  38. /** Start considering the current thread to be the 'main thread'. This has
  39. * no effect on anything besides in_main_thread(). */
  40. void
  41. set_main_thread(void)
  42. {
  43. main_thread_id = tor_get_thread_id();
  44. }
  45. /** Return true iff called from the main thread. */
  46. int
  47. in_main_thread(void)
  48. {
  49. return main_thread_id == tor_get_thread_id();
  50. }
  51. #ifndef HAVE_WORKING_STDATOMIC
  52. /** Initialize a new atomic counter with the value 0 */
  53. void
  54. atomic_counter_init(atomic_counter_t *counter)
  55. {
  56. memset(counter, 0, sizeof(*counter));
  57. tor_mutex_init_nonrecursive(&counter->mutex);
  58. }
  59. /** Clean up all resources held by an atomic counter. */
  60. void
  61. atomic_counter_destroy(atomic_counter_t *counter)
  62. {
  63. tor_mutex_uninit(&counter->mutex);
  64. memset(counter, 0, sizeof(*counter));
  65. }
  66. /** Add a value to an atomic counter. */
  67. void
  68. atomic_counter_add(atomic_counter_t *counter, size_t add)
  69. {
  70. tor_mutex_acquire(&counter->mutex);
  71. counter->val += add;
  72. tor_mutex_release(&counter->mutex);
  73. }
  74. /** Subtract a value from an atomic counter. */
  75. void
  76. atomic_counter_sub(atomic_counter_t *counter, size_t sub)
  77. {
  78. // this relies on unsigned overflow, but that's fine.
  79. atomic_counter_add(counter, -sub);
  80. }
  81. /** Return the current value of an atomic counter */
  82. size_t
  83. atomic_counter_get(atomic_counter_t *counter)
  84. {
  85. size_t val;
  86. tor_mutex_acquire(&counter->mutex);
  87. val = counter->val;
  88. tor_mutex_release(&counter->mutex);
  89. return val;
  90. }
  91. /** Replace the value of an atomic counter; return the old one. */
  92. size_t
  93. atomic_counter_exchange(atomic_counter_t *counter, size_t newval)
  94. {
  95. size_t oldval;
  96. tor_mutex_acquire(&counter->mutex);
  97. oldval = counter->val;
  98. counter->val = newval;
  99. tor_mutex_release(&counter->mutex);
  100. return oldval;
  101. }
  102. #endif /* !defined(HAVE_WORKING_STDATOMIC) */