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