LCOV - code coverage report
Current view: top level - lib/thread - compat_threads.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 16 16 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 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             : };

Generated by: LCOV version 1.14