1/**
2 * @copyright
3 * ====================================================================
4 *    Licensed to the Apache Software Foundation (ASF) under one
5 *    or more contributor license agreements.  See the NOTICE file
6 *    distributed with this work for additional information
7 *    regarding copyright ownership.  The ASF licenses this file
8 *    to you under the Apache License, Version 2.0 (the
9 *    "License"); you may not use this file except in compliance
10 *    with the License.  You may obtain a copy of the License at
11 *
12 *      http://www.apache.org/licenses/LICENSE-2.0
13 *
14 *    Unless required by applicable law or agreed to in writing,
15 *    software distributed under the License is distributed on an
16 *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 *    KIND, either express or implied.  See the License for the
18 *    specific language governing permissions and limitations
19 *    under the License.
20 * ====================================================================
21 * @endcopyright
22 *
23 * @file svn_named_atomics.h
24 * @brief Structures and functions for machine-wide named atomics.
25 *        These atomics store 64 bit signed integer values and provide
26 *        a number of basic operations on them. Instead of an address,
27 *        these atomics are identified by strings / names.  We also support
28 *        namespaces - mainly to separate debug from production data.
29 */
30
31#ifndef SVN_NAMED_ATOMICS_H
32#define SVN_NAMED_ATOMICS_H
33
34#include "svn_error.h"
35
36#ifdef __cplusplus
37extern "C" {
38#endif /* __cplusplus */
39
40/** An opaque structure that represents a namespace, i.e. a container
41 * for named atomics.
42 */
43typedef struct svn_atomic_namespace__t svn_atomic_namespace__t;
44
45/** An opaque structure that represents a named, system-wide visible
46 * 64 bit integer with atomic access routines.
47 */
48typedef struct svn_named_atomic__t svn_named_atomic__t;
49
50/** Maximum length of the name of any atomic (excluding the terminal NUL).
51 */
52#define SVN_NAMED_ATOMIC__MAX_NAME_LENGTH 30
53
54/** Returns #FALSE when named atomics are not available to our process
55 * and svn_atomic_namespace__create is likely to fail.
56 *
57 * @note The actual check will be performed only once and later
58 * changes in process privileges will not reflect in the outcome of future
59 * calls to this function.
60 */
61svn_boolean_t
62svn_named_atomic__is_supported(void);
63
64/** Returns #TRUE on platforms that don't need expensive synchronization
65 * objects to serialize access to named atomics. If this returns #FALSE,
66 * reading from or modifying a #svn_named_atomic__t may be as expensive
67 * as a file system operation.
68 */
69svn_boolean_t
70svn_named_atomic__is_efficient(void);
71
72/** Create a namespace (i.e. access object) with the given @a name and
73 * return it in @a *ns.
74 *
75 * Multiple access objects with the same name may be created.  They access
76 * the same shared memory region but have independent lifetimes.
77 *
78 * The access object will be allocated in @a result_pool and atomics gotten
79 * from this object will become invalid when the pool is being cleared.
80 */
81svn_error_t *
82svn_atomic_namespace__create(svn_atomic_namespace__t **ns,
83                             const char *name,
84                             apr_pool_t *result_pool);
85
86/** Removes persistent data structures (files in particular) that got
87 * created for the namespace given by @a name.  Use @a pool for temporary
88 * allocations.
89 *
90 * @note You must not call this while the respective namespace is still
91 * in use. Calling this multiple times for the same namespace is safe.
92 */
93svn_error_t *
94svn_atomic_namespace__cleanup(const char *name,
95                              apr_pool_t *pool);
96
97/** Find the atomic with the specified @a name in namespace @a ns and
98 * return it in @a *atomic.  If no object with that name can be found, the
99 * behavior depends on @a auto_create.  If it is @c FALSE, @a *atomic will
100 * be set to @c NULL. Otherwise, a new atomic will be created, its value
101 * set to 0 and the access structure be returned in @a *atomic.
102 *
103 * Note that @a name must not exceed #SVN_NAMED_ATOMIC__MAX_NAME_LENGTH
104 * characters and an error will be returned if the specified name is longer
105 * than supported.
106 *
107 * @note The lifetime of the atomic object is bound to the lifetime
108 * of the @a ns object, i.e. the pool the latter was created in.
109 * The data in the namespace persists as long as at least one process
110 * holds an #svn_atomic_namespace__t object corresponding to it.
111 */
112svn_error_t *
113svn_named_atomic__get(svn_named_atomic__t **atomic,
114                      svn_atomic_namespace__t *ns,
115                      const char *name,
116                      svn_boolean_t auto_create);
117
118/** Read the @a atomic and return its current @a *value.
119 * An error will be returned if @a atomic is @c NULL.
120 */
121svn_error_t *
122svn_named_atomic__read(apr_int64_t *value,
123                       svn_named_atomic__t *atomic);
124
125/** Set the data in @a atomic to @a new_value and return its old content
126 * in @a *old_value.  @a old_value may be NULL.
127 *
128 * An error will be returned if @a atomic is @c NULL.
129 */
130svn_error_t *
131svn_named_atomic__write(apr_int64_t *old_value,
132                        apr_int64_t new_value,
133                        svn_named_atomic__t *atomic);
134
135/** Add @a delta to the data in @a atomic and return its new value in
136 * @a *new_value.  @a new_value may be null.
137 *
138 * An error will be returned if @a atomic is @c NULL.
139 */
140svn_error_t *
141svn_named_atomic__add(apr_int64_t *new_value,
142                      apr_int64_t delta,
143                      svn_named_atomic__t *atomic);
144
145/** If the current data in @a atomic equals @a comperand, set it to
146 * @a new_value.  Return the initial value in @a *old_value.
147 * @a old_value may be NULL.
148 *
149 * An error will be returned if @a atomic is @c NULL.
150 */
151svn_error_t *
152svn_named_atomic__cmpxchg(apr_int64_t *old_value,
153                          apr_int64_t new_value,
154                          apr_int64_t comperand,
155                          svn_named_atomic__t *atomic);
156
157
158#ifdef __cplusplus
159}
160#endif /* __cplusplus */
161
162#endif /* SVN_NAMED_ATOMICS_H */
163