LCOV - code coverage report
Current view: top level - lib/thread - threads.h (source / functions) Hit Total Coverage
Test: lcov.info Lines: 13 13 100.0 %
Date: 2021-11-24 03:28:48 Functions: 5 5 100.0 %

          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 threads.h
       8             :  * \brief Header for threads.c
       9             :  **/
      10             : 
      11             : #ifndef TOR_COMPAT_THREADS_H
      12             : #define TOR_COMPAT_THREADS_H
      13             : 
      14             : #include "orconfig.h"
      15             : #include "lib/cc/torint.h"
      16             : #include "lib/testsupport/testsupport.h"
      17             : #include "lib/lock/compat_mutex.h"
      18             : 
      19             : #if defined(HAVE_STDATOMIC_H) && defined(STDATOMIC_WORKS)
      20             : #define HAVE_WORKING_STDATOMIC
      21             : #endif
      22             : 
      23             : #ifdef HAVE_WORKING_STDATOMIC
      24             : #include <stdatomic.h>
      25             : #endif
      26             : 
      27             : struct timeval;
      28             : 
      29             : int spawn_func(void (*func)(void *), void *data);
      30             : void spawn_exit(void) ATTR_NORETURN;
      31             : 
      32             : unsigned long tor_get_thread_id(void);
      33             : void tor_threads_init(void);
      34             : 
      35             : /** Conditions need nonrecursive mutexes with pthreads. */
      36             : #define tor_mutex_init_for_cond(m) tor_mutex_init_nonrecursive(m)
      37             : 
      38             : void set_main_thread(void);
      39             : int in_main_thread(void);
      40             : 
      41             : typedef struct tor_cond_t {
      42             : #ifdef USE_PTHREADS
      43             :   pthread_cond_t cond;
      44             : #elif defined(USE_WIN32_THREADS)
      45             :   CONDITION_VARIABLE cond;
      46             : #else
      47             : #error no known condition implementation.
      48             : #endif /* defined(USE_PTHREADS) || ... */
      49             : } tor_cond_t;
      50             : 
      51             : tor_cond_t *tor_cond_new(void);
      52             : void tor_cond_free_(tor_cond_t *cond);
      53             : #define tor_cond_free(c) FREE_AND_NULL(tor_cond_t, tor_cond_free_, (c))
      54             : int tor_cond_init(tor_cond_t *cond);
      55             : void tor_cond_uninit(tor_cond_t *cond);
      56             : int tor_cond_wait(tor_cond_t *cond, tor_mutex_t *mutex,
      57             :                   const struct timeval *tv);
      58             : void tor_cond_signal_one(tor_cond_t *cond);
      59             : void tor_cond_signal_all(tor_cond_t *cond);
      60             : 
      61             : typedef struct tor_threadlocal_t {
      62             : #ifdef _WIN32
      63             :   DWORD index;
      64             : #else
      65             :   pthread_key_t key;
      66             : #endif
      67             : } tor_threadlocal_t;
      68             : 
      69             : /** Initialize a thread-local variable.
      70             :  *
      71             :  * After you call this function on a tor_threadlocal_t, you can call
      72             :  * tor_threadlocal_set to change the current value of this variable for the
      73             :  * current thread, and tor_threadlocal_get to retrieve the current value for
      74             :  * the current thread.  Each thread has its own value.
      75             :  **/
      76             : int tor_threadlocal_init(tor_threadlocal_t *threadlocal);
      77             : /**
      78             :  * Release all resource associated with a thread-local variable.
      79             :  */
      80             : void tor_threadlocal_destroy(tor_threadlocal_t *threadlocal);
      81             : /**
      82             :  * Return the current value of a thread-local variable for this thread.
      83             :  *
      84             :  * It's undefined behavior to use this function if the threadlocal hasn't
      85             :  * been initialized, or has been destroyed.
      86             :  */
      87             : void *tor_threadlocal_get(tor_threadlocal_t *threadlocal);
      88             : /**
      89             :  * Change the current value of a thread-local variable for this thread to
      90             :  * <b>value</b>.
      91             :  *
      92             :  * It's undefined behavior to use this function if the threadlocal hasn't
      93             :  * been initialized, or has been destroyed.
      94             :  */
      95             : void tor_threadlocal_set(tor_threadlocal_t *threadlocal, void *value);
      96             : 
      97             : /**
      98             :  * Atomic counter type; holds a size_t value.
      99             :  */
     100             : #ifdef HAVE_WORKING_STDATOMIC
     101             : typedef struct atomic_counter_t {
     102             :   atomic_size_t val;
     103             : } atomic_counter_t;
     104             : #ifndef COCCI
     105             : #define ATOMIC_LINKAGE static
     106             : #endif
     107             : #else /* !defined(HAVE_WORKING_STDATOMIC) */
     108             : typedef struct atomic_counter_t {
     109             :   tor_mutex_t mutex;
     110             :   size_t val;
     111             : } atomic_counter_t;
     112             : #define ATOMIC_LINKAGE
     113             : #endif /* defined(HAVE_WORKING_STDATOMIC) */
     114             : 
     115             : ATOMIC_LINKAGE void atomic_counter_init(atomic_counter_t *counter);
     116             : ATOMIC_LINKAGE void atomic_counter_destroy(atomic_counter_t *counter);
     117             : ATOMIC_LINKAGE void atomic_counter_add(atomic_counter_t *counter, size_t add);
     118             : ATOMIC_LINKAGE void atomic_counter_sub(atomic_counter_t *counter, size_t sub);
     119             : ATOMIC_LINKAGE size_t atomic_counter_get(atomic_counter_t *counter);
     120             : ATOMIC_LINKAGE size_t atomic_counter_exchange(atomic_counter_t *counter,
     121             :                                               size_t newval);
     122             : #undef ATOMIC_LINKAGE
     123             : 
     124             : #ifdef HAVE_WORKING_STDATOMIC
     125             : /** Initialize a new atomic counter with the value 0 */
     126             : static inline void
     127       49001 : atomic_counter_init(atomic_counter_t *counter)
     128             : {
     129       49001 :   atomic_init(&counter->val, 0);
     130       49001 : }
     131             : /** Clean up all resources held by an atomic counter.
     132             :  *
     133             :  * This usage note applies to the compat_threads implementation of
     134             :  * atomic_counter_destroy():
     135             :  * Destroying a locked mutex is undefined behaviour. Global mutexes may be
     136             :  * locked when they are passed to this function, because multiple threads can
     137             :  * still access them. So we can either:
     138             :  *  - destroy on shutdown, and re-initialise when tor re-initialises, or
     139             :  *  - skip destroying and re-initialisation, using a sentinel variable.
     140             :  * See #31735 for details.
     141             :  */
     142             : static inline void
     143             : atomic_counter_destroy(atomic_counter_t *counter)
     144             : {
     145             :   (void)counter;
     146             : }
     147             : /** Add a value to an atomic counter. */
     148             : static inline void
     149         800 : atomic_counter_add(atomic_counter_t *counter, size_t add)
     150             : {
     151         800 :   (void) atomic_fetch_add(&counter->val, add);
     152         800 : }
     153             : /** Subtract a value from an atomic counter. */
     154             : static inline void
     155         800 : atomic_counter_sub(atomic_counter_t *counter, size_t sub)
     156             : {
     157         800 :   (void) atomic_fetch_sub(&counter->val, sub);
     158         800 : }
     159             : /** Return the current value of an atomic counter */
     160             : static inline size_t
     161         520 : atomic_counter_get(atomic_counter_t *counter)
     162             : {
     163         520 :   return atomic_load(&counter->val);
     164             : }
     165             : /** Replace the value of an atomic counter; return the old one. */
     166             : static inline size_t
     167        5766 : atomic_counter_exchange(atomic_counter_t *counter, size_t newval)
     168             : {
     169        5766 :   return atomic_exchange(&counter->val, newval);
     170             : }
     171             : 
     172             : #else /* !defined(HAVE_WORKING_STDATOMIC) */
     173             : #endif /* defined(HAVE_WORKING_STDATOMIC) */
     174             : 
     175             : #endif /* !defined(TOR_COMPAT_THREADS_H) */

Generated by: LCOV version 1.14