1 /**********************************************************************
2  * $Id: cpl_atomic_ops.h 355b41831cd2685c85d1aabe5b95665a2c6e99b7 2019-06-19 17:07:04 +0200 Even Rouault $
3  *
4  * Name:     cpl_atomic_ops.h
5  * Project:  CPL - Common Portability Library
6  * Purpose:  Atomic operation functions.
7  * Author:   Even Rouault, <even dot rouault at spatialys.com>
8  *
9  **********************************************************************
10  * Copyright (c) 2009-2010, Even Rouault <even dot rouault at spatialys.com>
11  *
12  * Permission is hereby granted, free of charge, to any person obtaining a
13  * copy of this software and associated documentation files (the "Software"),
14  * to deal in the Software without restriction, including without limitation
15  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16  * and/or sell copies of the Software, and to permit persons to whom the
17  * Software is furnished to do so, subject to the following conditions:
18  *
19  * The above copyright notice and this permission notice shall be included
20  * in all copies or substantial portions of the Software.
21  *
22  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
25  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28  * DEALINGS IN THE SOFTWARE.
29  ****************************************************************************/
30 
31 #ifndef CPL_ATOMIC_OPS_INCLUDED
32 #define CPL_ATOMIC_OPS_INCLUDED
33 
34 #include "cpl_port.h"
35 
36 CPL_C_START
37 
38 /** Add a value to a pointed integer in a thread and SMP-safe way
39   * and return the resulting value of the operation.
40   *
41   * This function, which in most cases is implemented by a few
42   * efficient machine instructions, guarantees that the value pointed
43   * by ptr will be incremented in a thread and SMP-safe way.
44   * The variables for this function must be aligned on a 32-bit boundary.
45   *
46   * Depending on the platforms, this function can also act as a
47   * memory barrier, but this should not be assumed.
48   *
49   * Current platforms/architectures where an efficient implementation
50   * exists are MacOSX, MS Windows, i386/x86_64 with GCC and platforms
51   * supported by GCC 4.1 or higher. For other platforms supporting
52   * the pthread library, and when GDAL is configured with thread-support,
53   * the atomicity will be done with a mutex, but with
54   * reduced efficiency. For the remaining platforms, a simple addition
55   * with no locking will be done...
56   *
57   * @param ptr a pointer to an integer to increment
58   * @param increment the amount to add to the pointed integer
59   * @return the pointed value AFTER the result of the addition
60   */
61 int CPL_DLL CPLAtomicAdd(volatile int* ptr, int increment);
62 
63 /** Increment of 1 the pointed integer in a thread and SMP-safe way
64   * and return the resulting value of the operation.
65   *
66   * @see CPLAtomicAdd for the details and guarantees of this atomic
67   *      operation
68   *
69   * @param ptr a pointer to an integer to increment
70   * @return the pointed value AFTER the operation: *ptr + 1
71   */
72 #define CPLAtomicInc(ptr) CPLAtomicAdd(ptr, 1)
73 
74 /** Decrement of 1 the pointed integer in a thread and SMP-safe way
75   * and return the resulting value of the operation.
76   *
77   * @see CPLAtomicAdd for the details and guarantees of this atomic
78   *      operation
79   *
80   * @param ptr a pointer to an integer to decrement
81   * @return the pointed value AFTER the operation: *ptr - 1
82   */
83 #define CPLAtomicDec(ptr) CPLAtomicAdd(ptr, -1)
84 
85 /** Compares *ptr with oldval. If *ptr == oldval, then *ptr is assigned
86   * newval and TRUE is returned. Otherwise nothing is done, and FALSE is returned.
87   *
88   * Current platforms/architectures where an efficient implementation
89   * exists are MacOSX, MS Windows, i386/x86_64 with GCC and platforms
90   * supported by GCC 4.1 or higher. For other platforms supporting
91   * the pthread library, and when GDAL is configured with thread-support,
92   * the atomicity will be done with a mutex, but with
93   * reduced efficiency. For the remaining platforms, a simple compare and
94   * exchange with no locking will be done...
95   *
96   * @param ptr a pointer to an integer (aligned on 32bit boundary).
97   * @param oldval old value
98   * @param newval new value
99   * @return TRUE if the exchange has been done
100   */
101 int CPLAtomicCompareAndExchange(volatile int* ptr, int oldval, int newval);
102 
103 CPL_C_END
104 
105 #endif /* CPL_ATOMIC_OPS_INCLUDED */
106