1
/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
* you may not use this file except in compliance with the License.
6
* You may obtain a copy of the License at
8
* http://www.apache.org/licenses/LICENSE-2.0
10
* Unless required by applicable law or agreed to in writing, software
11
* distributed under the License is distributed on an "AS IS" BASIS,
12
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
* See the License for the specific language governing permissions and
14
* limitations under the License.
18
#include "apr_atomic.h"
19
#include "apr_thread_mutex.h"
21
#if !defined(apr_atomic_init) && !defined(APR_OVERRIDE_ATOMIC_INIT)
24
#define NUM_ATOMIC_HASH 7
25
/* shift by 2 to get rid of alignment issues */
26
#define ATOMIC_HASH(x) (unsigned int)(((unsigned long)(x)>>2)%(unsigned int)NUM_ATOMIC_HASH)
27
static apr_thread_mutex_t **hash_mutex;
28
#endif /* APR_HAS_THREADS */
30
apr_status_t apr_atomic_init(apr_pool_t *p)
35
hash_mutex = apr_palloc(p, sizeof(apr_thread_mutex_t*) * NUM_ATOMIC_HASH);
37
for (i = 0; i < NUM_ATOMIC_HASH; i++) {
38
rv = apr_thread_mutex_create(&(hash_mutex[i]),
39
APR_THREAD_MUTEX_DEFAULT, p);
40
if (rv != APR_SUCCESS) {
44
#endif /* APR_HAS_THREADS */
47
#endif /*!defined(apr_atomic_init) && !defined(APR_OVERRIDE_ATOMIC_INIT) */
49
#if !defined(apr_atomic_add) && !defined(APR_OVERRIDE_ATOMIC_ADD)
50
void apr_atomic_add(volatile apr_atomic_t *mem, apr_uint32_t val)
53
apr_thread_mutex_t *lock = hash_mutex[ATOMIC_HASH(mem)];
56
if (apr_thread_mutex_lock(lock) == APR_SUCCESS) {
59
apr_thread_mutex_unlock(lock);
63
#endif /* APR_HAS_THREADS */
65
#endif /*!defined(apr_atomic_add) && !defined(APR_OVERRIDE_ATOMIC_ADD) */
67
#if !defined(apr_atomic_set) && !defined(APR_OVERRIDE_ATOMIC_SET)
68
void apr_atomic_set(volatile apr_atomic_t *mem, apr_uint32_t val)
71
apr_thread_mutex_t *lock = hash_mutex[ATOMIC_HASH(mem)];
74
if (apr_thread_mutex_lock(lock) == APR_SUCCESS) {
77
apr_thread_mutex_unlock(lock);
81
#endif /* APR_HAS_THREADS */
83
#endif /*!defined(apr_atomic_set) && !defined(APR_OVERRIDE_ATOMIC_SET) */
85
#if !defined(apr_atomic_inc) && !defined(APR_OVERRIDE_ATOMIC_INC)
86
void apr_atomic_inc(volatile apr_uint32_t *mem)
89
apr_thread_mutex_t *lock = hash_mutex[ATOMIC_HASH(mem)];
92
if (apr_thread_mutex_lock(lock) == APR_SUCCESS) {
95
apr_thread_mutex_unlock(lock);
99
#endif /* APR_HAS_THREADS */
101
#endif /*!defined(apr_atomic_inc) && !defined(APR_OVERRIDE_ATOMIC_INC) */
103
#if !defined(apr_atomic_dec) && !defined(APR_OVERRIDE_ATOMIC_DEC)
104
int apr_atomic_dec(volatile apr_atomic_t *mem)
107
apr_thread_mutex_t *lock = hash_mutex[ATOMIC_HASH(mem)];
110
if (apr_thread_mutex_lock(lock) == APR_SUCCESS) {
113
apr_thread_mutex_unlock(lock);
118
#endif /* APR_HAS_THREADS */
121
#endif /*!defined(apr_atomic_dec) && !defined(APR_OVERRIDE_ATOMIC_DEC) */
123
#if !defined(apr_atomic_cas) && !defined(APR_OVERRIDE_ATOMIC_CAS)
124
apr_uint32_t apr_atomic_cas(volatile apr_uint32_t *mem, long with, long cmp)
128
apr_thread_mutex_t *lock = hash_mutex[ATOMIC_HASH(mem)];
130
if (apr_thread_mutex_lock(lock) == APR_SUCCESS) {
135
apr_thread_mutex_unlock(lock);
145
#endif /* APR_HAS_THREADS */
147
#endif /*!defined(apr_atomic_cas) && !defined(APR_OVERRIDE_ATOMIC_CAS) */
149
#if !defined(apr_atomic_casptr) && !defined(APR_OVERRIDE_ATOMIC_CASPTR)
150
void *apr_atomic_casptr(volatile void **mem, void *with, const void *cmp)
154
apr_thread_mutex_t *lock = hash_mutex[ATOMIC_HASH(mem)];
156
if (apr_thread_mutex_lock(lock) == APR_SUCCESS) {
157
prev = *(void **)mem;
161
apr_thread_mutex_unlock(lock);
164
return *(void **)mem;
166
prev = *(void **)mem;
171
#endif /* APR_HAS_THREADS */
173
#endif /*!defined(apr_atomic_cas) && !defined(APR_OVERRIDE_ATOMIC_CAS) */