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_named_atomics.h
24251881Speter * @brief Structures and functions for machine-wide named atomics.
25251881Speter *        These atomics store 64 bit signed integer values and provide
26251881Speter *        a number of basic operations on them. Instead of an address,
27251881Speter *        these atomics are identified by strings / names.  We also support
28251881Speter *        namespaces - mainly to separate debug from production data.
29251881Speter */
30251881Speter
31251881Speter#ifndef SVN_NAMED_ATOMICS_H
32251881Speter#define SVN_NAMED_ATOMICS_H
33251881Speter
34251881Speter#include "svn_error.h"
35251881Speter
36251881Speter#ifdef __cplusplus
37251881Speterextern "C" {
38251881Speter#endif /* __cplusplus */
39251881Speter
40251881Speter/** An opaque structure that represents a namespace, i.e. a container
41251881Speter * for named atomics.
42251881Speter */
43251881Spetertypedef struct svn_atomic_namespace__t svn_atomic_namespace__t;
44251881Speter
45251881Speter/** An opaque structure that represents a named, system-wide visible
46251881Speter * 64 bit integer with atomic access routines.
47251881Speter */
48251881Spetertypedef struct svn_named_atomic__t svn_named_atomic__t;
49251881Speter
50251881Speter/** Maximum length of the name of any atomic (excluding the terminal NUL).
51251881Speter */
52251881Speter#define SVN_NAMED_ATOMIC__MAX_NAME_LENGTH 30
53251881Speter
54251881Speter/** Returns #FALSE when named atomics are not available to our process
55251881Speter * and svn_atomic_namespace__create is likely to fail.
56251881Speter *
57251881Speter * @note The actual check will be performed only once and later
58251881Speter * changes in process privileges will not reflect in the outcome of future
59251881Speter * calls to this function.
60251881Speter */
61251881Spetersvn_boolean_t
62251881Spetersvn_named_atomic__is_supported(void);
63251881Speter
64251881Speter/** Returns #TRUE on platforms that don't need expensive synchronization
65251881Speter * objects to serialize access to named atomics. If this returns #FALSE,
66251881Speter * reading from or modifying a #svn_named_atomic__t may be as expensive
67251881Speter * as a file system operation.
68251881Speter */
69251881Spetersvn_boolean_t
70251881Spetersvn_named_atomic__is_efficient(void);
71251881Speter
72251881Speter/** Create a namespace (i.e. access object) with the given @a name and
73251881Speter * return it in @a *ns.
74251881Speter *
75251881Speter * Multiple access objects with the same name may be created.  They access
76251881Speter * the same shared memory region but have independent lifetimes.
77251881Speter *
78251881Speter * The access object will be allocated in @a result_pool and atomics gotten
79251881Speter * from this object will become invalid when the pool is being cleared.
80251881Speter */
81251881Spetersvn_error_t *
82251881Spetersvn_atomic_namespace__create(svn_atomic_namespace__t **ns,
83251881Speter                             const char *name,
84251881Speter                             apr_pool_t *result_pool);
85251881Speter
86251881Speter/** Removes persistent data structures (files in particular) that got
87251881Speter * created for the namespace given by @a name.  Use @a pool for temporary
88251881Speter * allocations.
89251881Speter *
90251881Speter * @note You must not call this while the respective namespace is still
91251881Speter * in use. Calling this multiple times for the same namespace is safe.
92251881Speter */
93251881Spetersvn_error_t *
94251881Spetersvn_atomic_namespace__cleanup(const char *name,
95251881Speter                              apr_pool_t *pool);
96251881Speter
97251881Speter/** Find the atomic with the specified @a name in namespace @a ns and
98251881Speter * return it in @a *atomic.  If no object with that name can be found, the
99251881Speter * behavior depends on @a auto_create.  If it is @c FALSE, @a *atomic will
100251881Speter * be set to @c NULL. Otherwise, a new atomic will be created, its value
101251881Speter * set to 0 and the access structure be returned in @a *atomic.
102251881Speter *
103251881Speter * Note that @a name must not exceed #SVN_NAMED_ATOMIC__MAX_NAME_LENGTH
104251881Speter * characters and an error will be returned if the specified name is longer
105251881Speter * than supported.
106251881Speter *
107251881Speter * @note The lifetime of the atomic object is bound to the lifetime
108251881Speter * of the @a ns object, i.e. the pool the latter was created in.
109251881Speter * The data in the namespace persists as long as at least one process
110251881Speter * holds an #svn_atomic_namespace__t object corresponding to it.
111251881Speter */
112251881Spetersvn_error_t *
113251881Spetersvn_named_atomic__get(svn_named_atomic__t **atomic,
114251881Speter                      svn_atomic_namespace__t *ns,
115251881Speter                      const char *name,
116251881Speter                      svn_boolean_t auto_create);
117251881Speter
118251881Speter/** Read the @a atomic and return its current @a *value.
119251881Speter * An error will be returned if @a atomic is @c NULL.
120251881Speter */
121251881Spetersvn_error_t *
122251881Spetersvn_named_atomic__read(apr_int64_t *value,
123251881Speter                       svn_named_atomic__t *atomic);
124251881Speter
125251881Speter/** Set the data in @a atomic to @a new_value and return its old content
126251881Speter * in @a *old_value.  @a old_value may be NULL.
127251881Speter *
128251881Speter * An error will be returned if @a atomic is @c NULL.
129251881Speter */
130251881Spetersvn_error_t *
131251881Spetersvn_named_atomic__write(apr_int64_t *old_value,
132251881Speter                        apr_int64_t new_value,
133251881Speter                        svn_named_atomic__t *atomic);
134251881Speter
135251881Speter/** Add @a delta to the data in @a atomic and return its new value in
136251881Speter * @a *new_value.  @a new_value may be null.
137251881Speter *
138251881Speter * An error will be returned if @a atomic is @c NULL.
139251881Speter */
140251881Spetersvn_error_t *
141251881Spetersvn_named_atomic__add(apr_int64_t *new_value,
142251881Speter                      apr_int64_t delta,
143251881Speter                      svn_named_atomic__t *atomic);
144251881Speter
145251881Speter/** If the current data in @a atomic equals @a comperand, set it to
146251881Speter * @a new_value.  Return the initial value in @a *old_value.
147251881Speter * @a old_value may be NULL.
148251881Speter *
149251881Speter * An error will be returned if @a atomic is @c NULL.
150251881Speter */
151251881Spetersvn_error_t *
152251881Spetersvn_named_atomic__cmpxchg(apr_int64_t *old_value,
153251881Speter                          apr_int64_t new_value,
154251881Speter                          apr_int64_t comperand,
155251881Speter                          svn_named_atomic__t *atomic);
156251881Speter
157251881Speter
158251881Speter#ifdef __cplusplus
159251881Speter}
160251881Speter#endif /* __cplusplus */
161251881Speter
162251881Speter#endif /* SVN_NAMED_ATOMICS_H */
163