/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
parcel Lucy;
/** Provide atomic memory operations.
*/
inert class Lucy::Util::Atomic { }
__C__
/** Compare and swap a pointer. Test whether the value at target
* matches old_value
. If it does, set target
to
* new_value
and return true. Otherwise, return false.
*/
static CHY_INLINE chy_bool_t
lucy_Atomic_cas_ptr(void *volatile *target, void *old_value, void *new_value);
/************************** Mac OS X 10.4 and later ***********************/
#ifdef CHY_HAS_OSATOMIC_CAS_PTR
#include
static CHY_INLINE chy_bool_t
lucy_Atomic_cas_ptr(void *volatile *target, void *old_value, void *new_value) {
return OSAtomicCompareAndSwapPtr(old_value, new_value, target);
}
/********************************** Windows *******************************/
#elif defined(CHY_HAS_WINDOWS_H)
chy_bool_t
lucy_Atomic_wrapped_cas_ptr(void *volatile *target, void *old_value,
void *new_value);
static CHY_INLINE chy_bool_t
lucy_Atomic_cas_ptr(void *volatile *target, void *old_value, void *new_value) {
return lucy_Atomic_wrapped_cas_ptr(target, old_value, new_value);
}
/**************************** Solaris 10 and later ************************/
#elif defined(CHY_HAS_SYS_ATOMIC_H)
#include
static CHY_INLINE chy_bool_t
lucy_Atomic_cas_ptr(void *volatile *target, void *old_value, void *new_value) {
return atomic_cas_ptr(target, old_value, new_value) == old_value;
}
/************************ Fall back to pthread.h. **************************/
#elif defined(CHY_HAS_PTHREAD_H)
#include
extern pthread_mutex_t lucy_Atomic_mutex;
static CHY_INLINE chy_bool_t
lucy_Atomic_cas_ptr(void *volatile *target, void *old_value, void *new_value) {
pthread_mutex_lock(&lucy_Atomic_mutex);
if (*target == old_value) {
*target = new_value;
pthread_mutex_unlock(&lucy_Atomic_mutex);
return true;
}
else {
pthread_mutex_unlock(&lucy_Atomic_mutex);
return false;
}
}
/******************** No support for atomics at all. ***********************/
#else
#error "No support for atomic operations."
#endif // Big platform if-else chain.
#ifdef LUCY_USE_SHORT_NAMES
#define Atomic_cas_ptr lucy_Atomic_cas_ptr
#endif
__END_C__