Line data Source code
1 : /* Copyright (c) 2003-2004, Roger Dingledine 2 : * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. 3 : * Copyright (c) 2007-2021, The Tor Project, Inc. */ 4 : /* See LICENSE for licensing information */ 5 : 6 : /** 7 : * \file compat_threads.c 8 : * 9 : * \brief Cross-platform threading and inter-thread communication logic. 10 : * (Platform-specific parts are written in the other compat_*threads 11 : * modules.) 12 : */ 13 : 14 : #include "orconfig.h" 15 : #include <stdlib.h> 16 : #include "lib/thread/threads.h" 17 : #include "lib/thread/thread_sys.h" 18 : 19 : #include "lib/log/log.h" 20 : #include "lib/log/util_bug.h" 21 : #include "lib/subsys/subsys.h" 22 : 23 : #include <string.h> 24 : 25 : /** Allocate and return a new condition variable. */ 26 : tor_cond_t * 27 2 : tor_cond_new(void) 28 : { 29 2 : tor_cond_t *cond = tor_malloc(sizeof(tor_cond_t)); 30 2 : if (BUG(tor_cond_init(cond)<0)) 31 : tor_free(cond); // LCOV_EXCL_LINE 32 2 : return cond; 33 : } 34 : 35 : /** Free all storage held in <b>c</b>. */ 36 : void 37 2 : tor_cond_free_(tor_cond_t *c) 38 : { 39 2 : if (!c) 40 : return; 41 2 : tor_cond_uninit(c); 42 2 : tor_free(c); 43 : } 44 : 45 : /** Identity of the "main" thread */ 46 : static unsigned long main_thread_id = -1; 47 : 48 : /** Start considering the current thread to be the 'main thread'. This has 49 : * no effect on anything besides in_main_thread(). */ 50 : void 51 5561 : set_main_thread(void) 52 : { 53 5561 : main_thread_id = tor_get_thread_id(); 54 5561 : } 55 : /** Return true iff called from the main thread. */ 56 : int 57 37 : in_main_thread(void) 58 : { 59 37 : return main_thread_id == tor_get_thread_id(); 60 : } 61 : 62 : #ifndef HAVE_WORKING_STDATOMIC 63 : /** Initialize a new atomic counter with the value 0 */ 64 : void 65 : atomic_counter_init(atomic_counter_t *counter) 66 : { 67 : memset(counter, 0, sizeof(*counter)); 68 : tor_mutex_init_nonrecursive(&counter->mutex); 69 : } 70 : /** Clean up all resources held by an atomic counter. 71 : * 72 : * Destroying a locked mutex is undefined behaviour. Global mutexes may be 73 : * locked when they are passed to this function, because multiple threads can 74 : * still access them. So we can either: 75 : * - destroy on shutdown, and re-initialise when tor re-initialises, or 76 : * - skip destroying and re-initialisation, using a sentinel variable. 77 : * See #31735 for details. 78 : */ 79 : void 80 : atomic_counter_destroy(atomic_counter_t *counter) 81 : { 82 : tor_mutex_uninit(&counter->mutex); 83 : memset(counter, 0, sizeof(*counter)); 84 : } 85 : /** Add a value to an atomic counter. */ 86 : void 87 : atomic_counter_add(atomic_counter_t *counter, size_t add) 88 : { 89 : tor_mutex_acquire(&counter->mutex); 90 : counter->val += add; 91 : tor_mutex_release(&counter->mutex); 92 : } 93 : /** Subtract a value from an atomic counter. */ 94 : void 95 : atomic_counter_sub(atomic_counter_t *counter, size_t sub) 96 : { 97 : // this relies on unsigned overflow, but that's fine. 98 : atomic_counter_add(counter, -sub); 99 : } 100 : /** Return the current value of an atomic counter */ 101 : size_t 102 : atomic_counter_get(atomic_counter_t *counter) 103 : { 104 : size_t val; 105 : tor_mutex_acquire(&counter->mutex); 106 : val = counter->val; 107 : tor_mutex_release(&counter->mutex); 108 : return val; 109 : } 110 : /** Replace the value of an atomic counter; return the old one. */ 111 : size_t 112 : atomic_counter_exchange(atomic_counter_t *counter, size_t newval) 113 : { 114 : size_t oldval; 115 : tor_mutex_acquire(&counter->mutex); 116 : oldval = counter->val; 117 : counter->val = newval; 118 : tor_mutex_release(&counter->mutex); 119 : return oldval; 120 : } 121 : #endif /* !defined(HAVE_WORKING_STDATOMIC) */ 122 : 123 : static int 124 5553 : subsys_threads_initialize(void) 125 : { 126 5553 : tor_threads_init(); 127 5553 : return 0; 128 : } 129 : 130 : const subsys_fns_t sys_threads = { 131 : .name = "threads", 132 : SUBSYS_DECLARE_LOCATION(), 133 : .supported = true, 134 : .level = -89, 135 : .initialize = subsys_threads_initialize, 136 : };