compat_threads.c 2.7 KB

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