tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

pratom.h (6004B)


      1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* This Source Code Form is subject to the terms of the Mozilla Public
      3 * License, v. 2.0. If a copy of the MPL was not distributed with this
      4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      5 
      6 /* GLOBAL FUNCTIONS:
      7 ** DESCRIPTION:
      8 **     PR Atomic operations
      9 */
     10 
     11 #ifndef pratom_h___
     12 #define pratom_h___
     13 
     14 #include "prtypes.h"
     15 #include "prlock.h"
     16 
     17 PR_BEGIN_EXTERN_C
     18 
     19 /*
     20 ** FUNCTION: PR_AtomicIncrement
     21 ** DESCRIPTION:
     22 **    Atomically increment a 32 bit value.
     23 ** INPUTS:
     24 **    val:  a pointer to the value to increment
     25 ** RETURN:
     26 **    the returned value is the result of the increment
     27 */
     28 NSPR_API(PRInt32)   PR_AtomicIncrement(PRInt32 *val);
     29 
     30 /*
     31 ** FUNCTION: PR_AtomicDecrement
     32 ** DESCRIPTION:
     33 **    Atomically decrement a 32 bit value.
     34 ** INPUTS:
     35 **    val:  a pointer to the value to decrement
     36 ** RETURN:
     37 **    the returned value is the result of the decrement
     38 */
     39 NSPR_API(PRInt32)   PR_AtomicDecrement(PRInt32 *val);
     40 
     41 /*
     42 ** FUNCTION: PR_AtomicSet
     43 ** DESCRIPTION:
     44 **    Atomically set a 32 bit value.
     45 ** INPUTS:
     46 **    val: A pointer to a 32 bit value to be set
     47 **    newval: The newvalue to assign to val
     48 ** RETURN:
     49 **    Returns the prior value
     50 */
     51 NSPR_API(PRInt32) PR_AtomicSet(PRInt32 *val, PRInt32 newval);
     52 
     53 /*
     54 ** FUNCTION: PR_AtomicAdd
     55 ** DESCRIPTION:
     56 **    Atomically add a 32 bit value.
     57 ** INPUTS:
     58 **    ptr:  a pointer to the value to increment
     59 **    val:  value to be added
     60 ** RETURN:
     61 **    the returned value is the result of the addition
     62 */
     63 NSPR_API(PRInt32)   PR_AtomicAdd(PRInt32 *ptr, PRInt32 val);
     64 
     65 /*
     66 ** MACRO: PR_ATOMIC_INCREMENT
     67 ** MACRO: PR_ATOMIC_DECREMENT
     68 ** MACRO: PR_ATOMIC_SET
     69 ** MACRO: PR_ATOMIC_ADD
     70 ** DESCRIPTION:
     71 **    Macro versions of the atomic operations.  They may be implemented
     72 **    as compiler intrinsics.
     73 **
     74 ** IMPORTANT NOTE TO NSPR MAINTAINERS:
     75 **    Implement these macros with compiler intrinsics only on platforms
     76 **    where the PR_AtomicXXX functions are truly atomic (i.e., where the
     77 **    configuration macro _PR_HAVE_ATOMIC_OPS is defined).  Otherwise,
     78 **    the macros and functions won't be compatible and can't be used
     79 **    interchangeably.
     80 */
     81 #if defined(_WIN32) && !defined(_WIN32_WCE) && \
     82    (!defined(_MSC_VER) || (_MSC_VER >= 1310))
     83 
     84 #include <intrin.h>
     85 
     86 #ifdef _MSC_VER
     87 #pragma intrinsic(_InterlockedIncrement)
     88 #pragma intrinsic(_InterlockedDecrement)
     89 #pragma intrinsic(_InterlockedExchange)
     90 #pragma intrinsic(_InterlockedExchangeAdd)
     91 #endif
     92 
     93 #define PR_ATOMIC_INCREMENT(val) _InterlockedIncrement((long volatile *)(val))
     94 #define PR_ATOMIC_DECREMENT(val) _InterlockedDecrement((long volatile *)(val))
     95 #define PR_ATOMIC_SET(val, newval) \
     96        _InterlockedExchange((long volatile *)(val), (long)(newval))
     97 #define PR_ATOMIC_ADD(ptr, val) \
     98        (_InterlockedExchangeAdd((long volatile *)(ptr), (long)(val)) + (val))
     99 
    100 #elif ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) && \
    101      ((defined(__APPLE__) && \
    102           (defined(__ppc__) || defined(__i386__) || defined(__x86_64__))) || \
    103       (defined(__linux__) && \
    104           ((defined(__i386__) && \
    105           defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)) || \
    106           defined(__ia64__) || defined(__x86_64__) || \
    107           defined(__powerpc__) || \
    108           (defined(__arm__) && \
    109           defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)) || \
    110           defined(__aarch64__) || defined(__alpha) || \
    111           (defined(__riscv) && \
    112           defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)) || \
    113           (defined(__mips__) && \
    114           defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)))))
    115 
    116 /*
    117 * Because the GCC manual warns that some processors may support
    118 * reduced functionality of __sync_lock_test_and_set, we test for the
    119 * processors that we believe support a full atomic exchange operation.
    120 */
    121 
    122 #define PR_ATOMIC_INCREMENT(val) __sync_add_and_fetch(val, 1)
    123 #define PR_ATOMIC_DECREMENT(val) __sync_sub_and_fetch(val, 1)
    124 #define PR_ATOMIC_SET(val, newval) __sync_lock_test_and_set(val, newval)
    125 #define PR_ATOMIC_ADD(ptr, val) __sync_add_and_fetch(ptr, val)
    126 
    127 #else
    128 
    129 #define PR_ATOMIC_INCREMENT(val) PR_AtomicIncrement(val)
    130 #define PR_ATOMIC_DECREMENT(val) PR_AtomicDecrement(val)
    131 #define PR_ATOMIC_SET(val, newval) PR_AtomicSet(val, newval)
    132 #define PR_ATOMIC_ADD(ptr, val) PR_AtomicAdd(ptr, val)
    133 
    134 #endif
    135 
    136 /*
    137 ** LIFO linked-list (stack)
    138 */
    139 typedef struct PRStackElemStr PRStackElem;
    140 
    141 struct PRStackElemStr {
    142    PRStackElem *prstk_elem_next;   /* next pointer MUST be at offset 0;
    143                                      assembly language code relies on this */
    144 };
    145 
    146 typedef struct PRStackStr PRStack;
    147 
    148 /*
    149 ** FUNCTION: PR_CreateStack
    150 ** DESCRIPTION:
    151 **    Create a stack, a LIFO linked list
    152 ** INPUTS:
    153 **    stack_name:  a pointer to string containing the name of the stack
    154 ** RETURN:
    155 **    A pointer to the created stack, if successful, else NULL.
    156 */
    157 NSPR_API(PRStack *) PR_CreateStack(const char *stack_name);
    158 
    159 /*
    160 ** FUNCTION: PR_StackPush
    161 ** DESCRIPTION:
    162 **    Push an element on the top of the stack
    163 ** INPUTS:
    164 **    stack:        pointer to the stack
    165 **    stack_elem:   pointer to the stack element
    166 ** RETURN:
    167 **    None
    168 */
    169 NSPR_API(void)          PR_StackPush(PRStack *stack, PRStackElem *stack_elem);
    170 
    171 /*
    172 ** FUNCTION: PR_StackPop
    173 ** DESCRIPTION:
    174 **    Remove the element on the top of the stack
    175 ** INPUTS:
    176 **    stack:        pointer to the stack
    177 ** RETURN:
    178 **    A pointer to the stack element removed from the top of the stack,
    179 **    if non-empty,
    180 **    else NULL
    181 */
    182 NSPR_API(PRStackElem *) PR_StackPop(PRStack *stack);
    183 
    184 /*
    185 ** FUNCTION: PR_DestroyStack
    186 ** DESCRIPTION:
    187 **    Destroy the stack
    188 ** INPUTS:
    189 **    stack:        pointer to the stack
    190 ** RETURN:
    191 **    PR_SUCCESS - if successfully deleted
    192 **    PR_FAILURE - if the stack is not empty
    193 **                  PR_GetError will return
    194 **                      PR_INVALID_STATE_ERROR - stack is not empty
    195 */
    196 NSPR_API(PRStatus)      PR_DestroyStack(PRStack *stack);
    197 
    198 PR_END_EXTERN_C
    199 
    200 #endif /* pratom_h___ */