1251881Speter/**
2251881Speter * @copyright
3251881Speter * ====================================================================
4251881Speter *    Licensed to the Apache Software Foundation (ASF) under one
5251881Speter *    or more contributor license agreements.  See the NOTICE file
6251881Speter *    distributed with this work for additional information
7251881Speter *    regarding copyright ownership.  The ASF licenses this file
8251881Speter *    to you under the Apache License, Version 2.0 (the
9251881Speter *    "License"); you may not use this file except in compliance
10251881Speter *    with the License.  You may obtain a copy of the License at
11251881Speter *
12251881Speter *      http://www.apache.org/licenses/LICENSE-2.0
13251881Speter *
14251881Speter *    Unless required by applicable law or agreed to in writing,
15251881Speter *    software distributed under the License is distributed on an
16251881Speter *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17251881Speter *    KIND, either express or implied.  See the License for the
18251881Speter *    specific language governing permissions and limitations
19251881Speter *    under the License.
20251881Speter * ====================================================================
21251881Speter * @endcopyright
22251881Speter *
23251881Speter * @file svn_atomic.h
24251881Speter * @brief Macros and functions for atomic operations
25251881Speter */
26251881Speter
27251881Speter#ifndef SVN_ATOMIC_H
28251881Speter#define SVN_ATOMIC_H
29251881Speter
30251881Speter#include <apr_version.h>
31251881Speter#include <apr_atomic.h>
32251881Speter
33251881Speter#include "svn_error.h"
34251881Speter#include "private/svn_dep_compat.h"
35251881Speter
36251881Speter#ifdef __cplusplus
37251881Speterextern "C" {
38251881Speter#endif /* __cplusplus */
39251881Speter
40251881Speter/**
41251881Speter * @name Macro definitions for atomic types and operations
42251881Speter *
43251881Speter * @note These are necessary because the apr_atomic API changed somewhat
44251881Speter *       between apr-0.x and apr-1.x.
45251881Speter * @{
46251881Speter */
47251881Speter
48251881Speter/** The type used by all the other atomic operations. */
49251881Speter#if APR_VERSION_AT_LEAST(1, 0, 0)
50251881Speter#define svn_atomic_t apr_uint32_t
51251881Speter#else
52251881Speter#define svn_atomic_t apr_atomic_t
53251881Speter#endif
54251881Speter
55251881Speter/** Atomically read an #svn_atomic_t from memory. */
56251881Speter#if APR_VERSION_AT_LEAST(1, 0, 0)
57251881Speter#define svn_atomic_read(mem) apr_atomic_read32((mem))
58251881Speter#else
59251881Speter#define svn_atomic_read(mem) apr_atomic_read((mem))
60251881Speter#endif
61251881Speter
62251881Speter/** Atomically set an #svn_atomic_t in memory. */
63251881Speter#if APR_VERSION_AT_LEAST(1, 0, 0)
64251881Speter#define svn_atomic_set(mem, val) apr_atomic_set32((mem), (val))
65251881Speter#else
66251881Speter#define svn_atomic_set(mem, val) apr_atomic_set((mem), (val))
67251881Speter#endif
68251881Speter
69251881Speter/** Atomically increment an #svn_atomic_t. */
70251881Speter#if APR_VERSION_AT_LEAST(1, 0, 0)
71251881Speter#define svn_atomic_inc(mem) apr_atomic_inc32(mem)
72251881Speter#else
73251881Speter#define svn_atomic_inc(mem) apr_atomic_inc(mem)
74251881Speter#endif
75251881Speter
76251881Speter/** Atomically decrement an #svn_atomic_t. */
77251881Speter#if APR_VERSION_AT_LEAST(1, 0, 0)
78251881Speter#define svn_atomic_dec(mem) apr_atomic_dec32(mem)
79251881Speter#else
80251881Speter#define svn_atomic_dec(mem) apr_atomic_dec(mem)
81251881Speter#endif
82251881Speter
83251881Speter/**
84251881Speter * Atomic compare-and-swap.
85251881Speter *
86251881Speter * Compare the value that @a mem points to with @a cmp. If they are
87251881Speter * the same swap the value with @a with.
88251881Speter *
89251881Speter * @note svn_atomic_cas should not be combined with the other
90251881Speter *       svn_atomic operations.  A comment in apr_atomic.h explains
91251881Speter *       that on some platforms, the CAS function is implemented in a
92251881Speter *       way that is incompatible with the other atomic operations.
93251881Speter */
94251881Speter#if APR_VERSION_AT_LEAST(1, 0, 0)
95251881Speter#define svn_atomic_cas(mem, with, cmp) \
96251881Speter    apr_atomic_cas32((mem), (with), (cmp))
97251881Speter#else
98251881Speter#define svn_atomic_cas(mem, with, cmp) \
99251881Speter    apr_atomic_cas((mem), (with), (cmp))
100251881Speter#endif
101251881Speter/** @} */
102251881Speter
103251881Speter/**
104251881Speter * Call an initialization function in a thread-safe manner.
105251881Speter *
106251881Speter * @a global_status must be a pointer to a global, zero-initialized
107251881Speter * #svn_atomic_t. @a init_func is a pointer to the function that performs
108251881Speter * the actual initialization. @a baton and and @a pool are passed on to the
109251881Speter * init_func for its use.
110251881Speter *
111251881Speter * @since New in 1.5.
112251881Speter */
113251881Spetersvn_error_t *
114251881Spetersvn_atomic__init_once(volatile svn_atomic_t *global_status,
115251881Speter                      svn_error_t *(*init_func)(void*,apr_pool_t*),
116251881Speter                      void *baton,
117251881Speter                      apr_pool_t* pool);
118251881Speter
119251881Speter#ifdef __cplusplus
120251881Speter}
121251881Speter#endif /* __cplusplus */
122251881Speter
123251881Speter#endif /* SVN_ATOMIC_H */
124