compat_threads.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  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/thread/thread_sys.h"
  16. #include "lib/log/log.h"
  17. #include "lib/log/util_bug.h"
  18. #include "lib/subsys/subsys.h"
  19. #include <string.h>
  20. /** Allocate and return a new condition variable. */
  21. tor_cond_t *
  22. tor_cond_new(void)
  23. {
  24. tor_cond_t *cond = tor_malloc(sizeof(tor_cond_t));
  25. if (BUG(tor_cond_init(cond)<0))
  26. tor_free(cond); // LCOV_EXCL_LINE
  27. return cond;
  28. }
  29. /** Free all storage held in <b>c</b>. */
  30. void
  31. tor_cond_free_(tor_cond_t *c)
  32. {
  33. if (!c)
  34. return;
  35. tor_cond_uninit(c);
  36. tor_free(c);
  37. }
  38. /** Identity of the "main" thread */
  39. static unsigned long main_thread_id = -1;
  40. /** Start considering the current thread to be the 'main thread'. This has
  41. * no effect on anything besides in_main_thread(). */
  42. void
  43. set_main_thread(void)
  44. {
  45. main_thread_id = tor_get_thread_id();
  46. }
  47. /** Return true iff called from the main thread. */
  48. int
  49. in_main_thread(void)
  50. {
  51. return main_thread_id == tor_get_thread_id();
  52. }
  53. #ifndef HAVE_WORKING_STDATOMIC
  54. /** Initialize a new atomic counter with the value 0 */
  55. void
  56. atomic_counter_init(atomic_counter_t *counter)
  57. {
  58. memset(counter, 0, sizeof(*counter));
  59. tor_mutex_init_nonrecursive(&counter->mutex);
  60. }
  61. /** Clean up all resources held by an atomic counter. */
  62. void
  63. atomic_counter_destroy(atomic_counter_t *counter)
  64. {
  65. tor_mutex_uninit(&counter->mutex);
  66. memset(counter, 0, sizeof(*counter));
  67. }
  68. /** Add a value to an atomic counter. */
  69. void
  70. atomic_counter_add(atomic_counter_t *counter, size_t add)
  71. {
  72. tor_mutex_acquire(&counter->mutex);
  73. counter->val += add;
  74. tor_mutex_release(&counter->mutex);
  75. }
  76. /** Subtract a value from an atomic counter. */
  77. void
  78. atomic_counter_sub(atomic_counter_t *counter, size_t sub)
  79. {
  80. // this relies on unsigned overflow, but that's fine.
  81. atomic_counter_add(counter, -sub);
  82. }
  83. /** Return the current value of an atomic counter */
  84. size_t
  85. atomic_counter_get(atomic_counter_t *counter)
  86. {
  87. size_t val;
  88. tor_mutex_acquire(&counter->mutex);
  89. val = counter->val;
  90. tor_mutex_release(&counter->mutex);
  91. return val;
  92. }
  93. /** Replace the value of an atomic counter; return the old one. */
  94. size_t
  95. atomic_counter_exchange(atomic_counter_t *counter, size_t newval)
  96. {
  97. size_t oldval;
  98. tor_mutex_acquire(&counter->mutex);
  99. oldval = counter->val;
  100. counter->val = newval;
  101. tor_mutex_release(&counter->mutex);
  102. return oldval;
  103. }
  104. #endif /* !defined(HAVE_WORKING_STDATOMIC) */
  105. static int
  106. subsys_threads_initialize(void)
  107. {
  108. tor_threads_init();
  109. return 0;
  110. }
  111. const subsys_fns_t sys_threads = {
  112. .name = "threads",
  113. .supported = true,
  114. /* Threads is used by logging, which is a diagnostic feature, we want it to
  115. * init right after low-level error handling and approx time. */
  116. .level = -95,
  117. .initialize = subsys_threads_initialize,
  118. };