Add Chromium-only Blender WebEngine parity work
This commit is contained in:
39
blender-5.2.0/intern/atomic/CMakeLists.txt
Normal file
39
blender-5.2.0/intern/atomic/CMakeLists.txt
Normal file
@@ -0,0 +1,39 @@
|
||||
# SPDX-FileCopyrightText: 2020 Blender Authors
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
set(INC
|
||||
.
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
)
|
||||
set(LIB
|
||||
)
|
||||
|
||||
add_library(bf_intern_atomic INTERFACE)
|
||||
|
||||
target_include_directories(bf_intern_atomic INTERFACE .)
|
||||
add_library(bf::intern::atomic ALIAS bf_intern_atomic)
|
||||
|
||||
set(SRC
|
||||
atomic_ops.h
|
||||
intern/atomic_ops_ext.h
|
||||
intern/atomic_ops_msvc.h
|
||||
intern/atomic_ops_unix.h
|
||||
intern/atomic_ops_utils.h
|
||||
)
|
||||
target_sources(bf_intern_atomic PRIVATE ${SRC})
|
||||
blender_source_group(bf_intern_atomic ${SRC})
|
||||
|
||||
if(WITH_GTESTS)
|
||||
set(TEST_SRC
|
||||
tests/atomic_test.cc
|
||||
)
|
||||
set(TEST_INC
|
||||
)
|
||||
set(TEST_LIB
|
||||
PRIVATE bf_intern_atomic
|
||||
)
|
||||
blender_add_test_executable(atomic "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB};${TEST_LIB}")
|
||||
endif()
|
||||
150
blender-5.2.0/intern/atomic/atomic_ops.h
Normal file
150
blender-5.2.0/intern/atomic/atomic_ops.h
Normal file
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Original code from jemalloc with this license:
|
||||
*
|
||||
* Copyright (C) 2002-2013 Jason Evans <jasone@canonware.com>.
|
||||
* All rights reserved.
|
||||
* Copyright (C) 2007-2012 Mozilla Foundation. All rights reserved.
|
||||
* Copyright (C) 2009-2013 Facebook, Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice(s),
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice(s),
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is adapted from jemalloc.
|
||||
* Modifications Copyright (C) 2016 Blender Foundation
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup intern_atomic
|
||||
*
|
||||
* \brief Provides wrapper around system-specific atomic primitives,
|
||||
* and some extensions (faked-atomic operations over float numbers).
|
||||
*/
|
||||
|
||||
#ifndef __ATOMIC_OPS_H__
|
||||
#define __ATOMIC_OPS_H__
|
||||
|
||||
#include "intern/atomic_ops_utils.h" /* IWYU pragma: export */
|
||||
|
||||
/******************************************************************************/
|
||||
/* Function prototypes. */
|
||||
|
||||
ATOMIC_INLINE uint64_t atomic_add_and_fetch_uint64(uint64_t *p, uint64_t x);
|
||||
ATOMIC_INLINE uint64_t atomic_sub_and_fetch_uint64(uint64_t *p, uint64_t x);
|
||||
ATOMIC_INLINE uint64_t atomic_fetch_and_add_uint64(uint64_t *p, uint64_t x);
|
||||
ATOMIC_INLINE uint64_t atomic_fetch_and_sub_uint64(uint64_t *p, uint64_t x);
|
||||
ATOMIC_INLINE uint64_t atomic_cas_uint64(uint64_t *v, uint64_t old, uint64_t _new);
|
||||
ATOMIC_INLINE uint64_t atomic_load_uint64(const uint64_t *v);
|
||||
ATOMIC_INLINE void atomic_store_uint64(uint64_t *p, uint64_t v);
|
||||
|
||||
ATOMIC_INLINE int64_t atomic_add_and_fetch_int64(int64_t *p, int64_t x);
|
||||
ATOMIC_INLINE int64_t atomic_sub_and_fetch_int64(int64_t *p, int64_t x);
|
||||
ATOMIC_INLINE int64_t atomic_fetch_and_add_int64(int64_t *p, int64_t x);
|
||||
ATOMIC_INLINE int64_t atomic_fetch_and_sub_int64(int64_t *p, int64_t x);
|
||||
ATOMIC_INLINE int64_t atomic_cas_int64(int64_t *v, int64_t old, int64_t _new);
|
||||
ATOMIC_INLINE int64_t atomic_load_int64(const int64_t *v);
|
||||
ATOMIC_INLINE void atomic_store_int64(int64_t *p, int64_t v);
|
||||
|
||||
ATOMIC_INLINE uint32_t atomic_add_and_fetch_uint32(uint32_t *p, uint32_t x);
|
||||
ATOMIC_INLINE uint32_t atomic_sub_and_fetch_uint32(uint32_t *p, uint32_t x);
|
||||
ATOMIC_INLINE uint32_t atomic_cas_uint32(uint32_t *v, uint32_t old, uint32_t _new);
|
||||
ATOMIC_INLINE uint32_t atomic_load_uint32(const uint32_t *v);
|
||||
ATOMIC_INLINE void atomic_store_uint32(uint32_t *p, uint32_t v);
|
||||
|
||||
ATOMIC_INLINE uint32_t atomic_fetch_and_add_uint32(uint32_t *p, uint32_t x);
|
||||
ATOMIC_INLINE uint32_t atomic_fetch_and_or_uint32(uint32_t *p, uint32_t x);
|
||||
ATOMIC_INLINE uint32_t atomic_fetch_and_and_uint32(uint32_t *p, uint32_t x);
|
||||
|
||||
ATOMIC_INLINE int32_t atomic_add_and_fetch_int32(int32_t *p, int32_t x);
|
||||
ATOMIC_INLINE int32_t atomic_sub_and_fetch_int32(int32_t *p, int32_t x);
|
||||
ATOMIC_INLINE int32_t atomic_cas_int32(int32_t *v, int32_t old, int32_t _new);
|
||||
ATOMIC_INLINE int32_t atomic_load_int32(const int32_t *v);
|
||||
ATOMIC_INLINE void atomic_store_int32(int32_t *p, int32_t v);
|
||||
|
||||
ATOMIC_INLINE int32_t atomic_fetch_and_add_int32(int32_t *p, int32_t x);
|
||||
ATOMIC_INLINE int32_t atomic_fetch_and_or_int32(int32_t *p, int32_t x);
|
||||
ATOMIC_INLINE int32_t atomic_fetch_and_and_int32(int32_t *p, int32_t x);
|
||||
|
||||
ATOMIC_INLINE int16_t atomic_fetch_and_or_int16(int16_t *p, int16_t b);
|
||||
ATOMIC_INLINE int16_t atomic_fetch_and_and_int16(int16_t *p, int16_t b);
|
||||
|
||||
ATOMIC_INLINE uint8_t atomic_fetch_and_or_uint8(uint8_t *p, uint8_t b);
|
||||
ATOMIC_INLINE uint8_t atomic_fetch_and_and_uint8(uint8_t *p, uint8_t b);
|
||||
|
||||
ATOMIC_INLINE int8_t atomic_fetch_and_or_int8(int8_t *p, int8_t b);
|
||||
ATOMIC_INLINE int8_t atomic_fetch_and_and_int8(int8_t *p, int8_t b);
|
||||
|
||||
ATOMIC_INLINE char atomic_fetch_and_or_char(char *p, char b);
|
||||
ATOMIC_INLINE char atomic_fetch_and_and_char(char *p, char b);
|
||||
|
||||
ATOMIC_INLINE size_t atomic_add_and_fetch_z(size_t *p, size_t x);
|
||||
ATOMIC_INLINE size_t atomic_sub_and_fetch_z(size_t *p, size_t x);
|
||||
ATOMIC_INLINE size_t atomic_fetch_and_add_z(size_t *p, size_t x);
|
||||
ATOMIC_INLINE size_t atomic_fetch_and_sub_z(size_t *p, size_t x);
|
||||
ATOMIC_INLINE size_t atomic_cas_z(size_t *v, size_t old, size_t _new);
|
||||
ATOMIC_INLINE size_t atomic_load_z(const size_t *v);
|
||||
ATOMIC_INLINE void atomic_store_z(size_t *p, size_t v);
|
||||
/* Uses CAS loop, see warning below. */
|
||||
ATOMIC_INLINE size_t atomic_fetch_and_update_max_z(size_t *p, size_t x);
|
||||
|
||||
ATOMIC_INLINE unsigned int atomic_add_and_fetch_u(unsigned int *p, unsigned int x);
|
||||
ATOMIC_INLINE unsigned int atomic_sub_and_fetch_u(unsigned int *p, unsigned int x);
|
||||
ATOMIC_INLINE unsigned int atomic_fetch_and_add_u(unsigned int *p, unsigned int x);
|
||||
ATOMIC_INLINE unsigned int atomic_fetch_and_sub_u(unsigned int *p, unsigned int x);
|
||||
ATOMIC_INLINE unsigned int atomic_cas_u(unsigned int *v, unsigned int old, unsigned int _new);
|
||||
|
||||
ATOMIC_INLINE void *atomic_cas_ptr(void **v, void *old, void *_new);
|
||||
ATOMIC_INLINE void *atomic_load_ptr(void *const *v);
|
||||
ATOMIC_INLINE void atomic_store_ptr(void **p, void *v);
|
||||
|
||||
ATOMIC_INLINE float atomic_cas_float(float *v, float old, float _new);
|
||||
|
||||
/* WARNING! Float 'atomics' are really faked ones, those are actually closer to some kind of
|
||||
* spinlock-sync'ed operation, which means they are only efficient if collisions are highly
|
||||
* unlikely (i.e. if probability of two threads working on the same pointer at the same time is
|
||||
* very low). */
|
||||
ATOMIC_INLINE float atomic_add_and_fetch_fl(float *p, const float x);
|
||||
|
||||
/******************************************************************************/
|
||||
/* Include system-dependent implementations. */
|
||||
|
||||
/* Note that we are using _unix flavor as fallback here
|
||||
* (it will raise precompiler errors as needed). */
|
||||
#if defined(_MSC_VER)
|
||||
# include "intern/atomic_ops_msvc.h" /* IWYU pragma: export */
|
||||
#else
|
||||
# include "intern/atomic_ops_unix.h" /* IWYU pragma: export */
|
||||
#endif
|
||||
|
||||
/* Include 'fake' atomic extensions, built over real atomic primitives. */
|
||||
#include "intern/atomic_ops_ext.h" /* IWYU pragma: export */
|
||||
|
||||
#endif /* __ATOMIC_OPS_H__ */
|
||||
248
blender-5.2.0/intern/atomic/intern/atomic_ops_ext.h
Normal file
248
blender-5.2.0/intern/atomic/intern/atomic_ops_ext.h
Normal file
@@ -0,0 +1,248 @@
|
||||
/*
|
||||
* Original code from jemalloc with this license:
|
||||
*
|
||||
* Copyright (C) 2002-2013 Jason Evans <jasone@canonware.com>.
|
||||
* All rights reserved.
|
||||
* Copyright (C) 2007-2012 Mozilla Foundation. All rights reserved.
|
||||
* Copyright (C) 2009-2013 Facebook, Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice(s),
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice(s),
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is adapted from jemalloc.
|
||||
* Modifications Copyright (C) 2016 Blender Foundation
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup intern_atomic
|
||||
*/
|
||||
|
||||
#ifndef __ATOMIC_OPS_EXT_H__
|
||||
#define __ATOMIC_OPS_EXT_H__
|
||||
|
||||
#include "atomic_ops_utils.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/* size_t operations. */
|
||||
ATOMIC_STATIC_ASSERT(sizeof(size_t) == LG_SIZEOF_PTR, "sizeof(size_t) != LG_SIZEOF_PTR");
|
||||
|
||||
ATOMIC_INLINE size_t atomic_add_and_fetch_z(size_t *p, size_t x)
|
||||
{
|
||||
#if (LG_SIZEOF_PTR == 8)
|
||||
return (size_t)atomic_add_and_fetch_uint64((uint64_t *)p, (uint64_t)x);
|
||||
#elif (LG_SIZEOF_PTR == 4)
|
||||
return (size_t)atomic_add_and_fetch_uint32((uint32_t *)p, (uint32_t)x);
|
||||
#endif
|
||||
}
|
||||
|
||||
ATOMIC_INLINE size_t atomic_sub_and_fetch_z(size_t *p, size_t x)
|
||||
{
|
||||
#if (LG_SIZEOF_PTR == 8)
|
||||
return (size_t)atomic_add_and_fetch_uint64((uint64_t *)p, (uint64_t)-((int64_t)x));
|
||||
#elif (LG_SIZEOF_PTR == 4)
|
||||
return (size_t)atomic_add_and_fetch_uint32((uint32_t *)p, (uint32_t)-((int32_t)x));
|
||||
#endif
|
||||
}
|
||||
|
||||
ATOMIC_INLINE size_t atomic_fetch_and_add_z(size_t *p, size_t x)
|
||||
{
|
||||
#if (LG_SIZEOF_PTR == 8)
|
||||
return (size_t)atomic_fetch_and_add_uint64((uint64_t *)p, (uint64_t)x);
|
||||
#elif (LG_SIZEOF_PTR == 4)
|
||||
return (size_t)atomic_fetch_and_add_uint32((uint32_t *)p, (uint32_t)x);
|
||||
#endif
|
||||
}
|
||||
|
||||
ATOMIC_INLINE size_t atomic_fetch_and_sub_z(size_t *p, size_t x)
|
||||
{
|
||||
#if (LG_SIZEOF_PTR == 8)
|
||||
return (size_t)atomic_fetch_and_add_uint64((uint64_t *)p, (uint64_t)-((int64_t)x));
|
||||
#elif (LG_SIZEOF_PTR == 4)
|
||||
return (size_t)atomic_fetch_and_add_uint32((uint32_t *)p, (uint32_t)-((int32_t)x));
|
||||
#endif
|
||||
}
|
||||
|
||||
ATOMIC_INLINE size_t atomic_cas_z(size_t *v, size_t old, size_t _new)
|
||||
{
|
||||
#if (LG_SIZEOF_PTR == 8)
|
||||
return (size_t)atomic_cas_uint64((uint64_t *)v, (uint64_t)old, (uint64_t)_new);
|
||||
#elif (LG_SIZEOF_PTR == 4)
|
||||
return (size_t)atomic_cas_uint32((uint32_t *)v, (uint32_t)old, (uint32_t)_new);
|
||||
#endif
|
||||
}
|
||||
|
||||
ATOMIC_INLINE size_t atomic_load_z(const size_t *v)
|
||||
{
|
||||
#if (LG_SIZEOF_PTR == 8)
|
||||
return (size_t)atomic_load_uint64((const uint64_t *)v);
|
||||
#elif (LG_SIZEOF_PTR == 4)
|
||||
return (size_t)atomic_load_uint32((const uint32_t *)v);
|
||||
#endif
|
||||
}
|
||||
|
||||
ATOMIC_INLINE void atomic_store_z(size_t *p, size_t v)
|
||||
{
|
||||
#if (LG_SIZEOF_PTR == 8)
|
||||
atomic_store_uint64((uint64_t *)p, v);
|
||||
#elif (LG_SIZEOF_PTR == 4)
|
||||
atomic_store_uint32((uint32_t *)p, v);
|
||||
#endif
|
||||
}
|
||||
|
||||
ATOMIC_INLINE size_t atomic_fetch_and_update_max_z(size_t *p, size_t x)
|
||||
{
|
||||
size_t prev_value;
|
||||
while ((prev_value = *p) < x) {
|
||||
if (atomic_cas_z(p, prev_value, x) == prev_value) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return prev_value;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* unsigned operations. */
|
||||
ATOMIC_STATIC_ASSERT(sizeof(unsigned int) == LG_SIZEOF_INT,
|
||||
"sizeof(unsigned int) != LG_SIZEOF_INT");
|
||||
|
||||
ATOMIC_INLINE unsigned int atomic_add_and_fetch_u(unsigned int *p, unsigned int x)
|
||||
{
|
||||
#if (LG_SIZEOF_INT == 8)
|
||||
return (unsigned int)atomic_add_and_fetch_uint64((uint64_t *)p, (uint64_t)x);
|
||||
#elif (LG_SIZEOF_INT == 4)
|
||||
return (unsigned int)atomic_add_and_fetch_uint32((uint32_t *)p, (uint32_t)x);
|
||||
#endif
|
||||
}
|
||||
|
||||
ATOMIC_INLINE unsigned int atomic_sub_and_fetch_u(unsigned int *p, unsigned int x)
|
||||
{
|
||||
#if (LG_SIZEOF_INT == 8)
|
||||
return (unsigned int)atomic_add_and_fetch_uint64((uint64_t *)p, (uint64_t)-((int64_t)x));
|
||||
#elif (LG_SIZEOF_INT == 4)
|
||||
return (unsigned int)atomic_add_and_fetch_uint32((uint32_t *)p, (uint32_t)-((int32_t)x));
|
||||
#endif
|
||||
}
|
||||
|
||||
ATOMIC_INLINE unsigned int atomic_fetch_and_add_u(unsigned int *p, unsigned int x)
|
||||
{
|
||||
#if (LG_SIZEOF_INT == 8)
|
||||
return (unsigned int)atomic_fetch_and_add_uint64((uint64_t *)p, (uint64_t)x);
|
||||
#elif (LG_SIZEOF_INT == 4)
|
||||
return (unsigned int)atomic_fetch_and_add_uint32((uint32_t *)p, (uint32_t)x);
|
||||
#endif
|
||||
}
|
||||
|
||||
ATOMIC_INLINE unsigned int atomic_fetch_and_sub_u(unsigned int *p, unsigned int x)
|
||||
{
|
||||
#if (LG_SIZEOF_INT == 8)
|
||||
return (unsigned int)atomic_fetch_and_add_uint64((uint64_t *)p, (uint64_t)-((int64_t)x));
|
||||
#elif (LG_SIZEOF_INT == 4)
|
||||
return (unsigned int)atomic_fetch_and_add_uint32((uint32_t *)p, (uint32_t)-((int32_t)x));
|
||||
#endif
|
||||
}
|
||||
|
||||
ATOMIC_INLINE unsigned int atomic_cas_u(unsigned int *v, unsigned int old, unsigned int _new)
|
||||
{
|
||||
#if (LG_SIZEOF_INT == 8)
|
||||
return (unsigned int)atomic_cas_uint64((uint64_t *)v, (uint64_t)old, (uint64_t)_new);
|
||||
#elif (LG_SIZEOF_INT == 4)
|
||||
return (unsigned int)atomic_cas_uint32((uint32_t *)v, (uint32_t)old, (uint32_t)_new);
|
||||
#endif
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* Char operations. */
|
||||
ATOMIC_INLINE char atomic_fetch_and_or_char(char *p, char b)
|
||||
{
|
||||
return (char)atomic_fetch_and_or_uint8((uint8_t *)p, (uint8_t)b);
|
||||
}
|
||||
|
||||
ATOMIC_INLINE char atomic_fetch_and_and_char(char *p, char b)
|
||||
{
|
||||
return (char)atomic_fetch_and_and_uint8((uint8_t *)p, (uint8_t)b);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* Pointer operations. */
|
||||
|
||||
ATOMIC_INLINE void *atomic_cas_ptr(void **v, void *old, void *_new)
|
||||
{
|
||||
#if (LG_SIZEOF_PTR == 8)
|
||||
return (void *)atomic_cas_uint64((uint64_t *)v, *(uint64_t *)&old, *(uint64_t *)&_new);
|
||||
#elif (LG_SIZEOF_PTR == 4)
|
||||
return (void *)atomic_cas_uint32((uint32_t *)v, *(uint32_t *)&old, *(uint32_t *)&_new);
|
||||
#endif
|
||||
}
|
||||
|
||||
ATOMIC_INLINE void *atomic_load_ptr(void *const *v)
|
||||
{
|
||||
#if (LG_SIZEOF_PTR == 8)
|
||||
return (void *)atomic_load_uint64((const uint64_t *)v);
|
||||
#elif (LG_SIZEOF_PTR == 4)
|
||||
return (void *)atomic_load_uint32((const uint32_t *)v);
|
||||
#endif
|
||||
}
|
||||
|
||||
ATOMIC_INLINE void atomic_store_ptr(void **p, void *v)
|
||||
{
|
||||
#if (LG_SIZEOF_PTR == 8)
|
||||
atomic_store_uint64((uint64_t *)p, (uint64_t)v);
|
||||
#elif (LG_SIZEOF_PTR == 4)
|
||||
atomic_store_uint32((uint32_t *)p, (uint32_t)v);
|
||||
#endif
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* float operations. */
|
||||
ATOMIC_STATIC_ASSERT(sizeof(float) == sizeof(uint32_t), "sizeof(float) != sizeof(uint32_t)");
|
||||
|
||||
ATOMIC_INLINE float atomic_cas_float(float *v, float old, float _new)
|
||||
{
|
||||
uint32_t ret = atomic_cas_uint32((uint32_t *)v, *(uint32_t *)&old, *(uint32_t *)&_new);
|
||||
return *(float *)&ret;
|
||||
}
|
||||
|
||||
ATOMIC_INLINE float atomic_add_and_fetch_fl(float *p, const float x)
|
||||
{
|
||||
float oldval, newval;
|
||||
uint32_t prevval;
|
||||
|
||||
do { /* Note that since collisions are unlikely, loop will nearly always run once. */
|
||||
oldval = *p;
|
||||
newval = oldval + x;
|
||||
prevval = atomic_cas_uint32((uint32_t *)p, *(uint32_t *)(&oldval), *(uint32_t *)(&newval));
|
||||
} while (_ATOMIC_UNLIKELY(prevval != *(uint32_t *)(&oldval)));
|
||||
|
||||
return newval;
|
||||
}
|
||||
|
||||
#endif /* __ATOMIC_OPS_EXT_H__ */
|
||||
284
blender-5.2.0/intern/atomic/intern/atomic_ops_msvc.h
Normal file
284
blender-5.2.0/intern/atomic/intern/atomic_ops_msvc.h
Normal file
@@ -0,0 +1,284 @@
|
||||
/*
|
||||
* Adopted from jemalloc with this license:
|
||||
*
|
||||
* Copyright (C) 2002-2013 Jason Evans <jasone@canonware.com>.
|
||||
* All rights reserved.
|
||||
* Copyright (C) 2007-2012 Mozilla Foundation. All rights reserved.
|
||||
* Copyright (C) 2009-2013 Facebook, Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice(s),
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice(s),
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup intern_atomic
|
||||
*/
|
||||
|
||||
#ifndef __ATOMIC_OPS_MSVC_H__
|
||||
#define __ATOMIC_OPS_MSVC_H__
|
||||
|
||||
#include "atomic_ops_utils.h"
|
||||
|
||||
#define NOGDI
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
#include <intrin.h>
|
||||
#include <windows.h>
|
||||
|
||||
#if defined(__clang__)
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wincompatible-pointer-types"
|
||||
#endif
|
||||
|
||||
/* TODO(sergey): On x64 platform both read and write of a variable aligned to its type size is
|
||||
* atomic, so in theory it is possible to avoid memory barrier and gain performance. The downside
|
||||
* of that would be that it will impose requirement to value which is being operated on. */
|
||||
#define __atomic_impl_load_generic(v) (MemoryBarrier(), *(v))
|
||||
#define __atomic_impl_store_generic(p, v) \
|
||||
do { \
|
||||
*(p) = (v); \
|
||||
MemoryBarrier(); \
|
||||
} while (0)
|
||||
|
||||
/* 64-bit operations. */
|
||||
/* Unsigned */
|
||||
ATOMIC_INLINE uint64_t atomic_add_and_fetch_uint64(uint64_t *p, uint64_t x)
|
||||
{
|
||||
return InterlockedExchangeAdd64((int64_t *)p, (int64_t)x) + x;
|
||||
}
|
||||
|
||||
ATOMIC_INLINE uint64_t atomic_sub_and_fetch_uint64(uint64_t *p, uint64_t x)
|
||||
{
|
||||
return InterlockedExchangeAdd64((int64_t *)p, -((int64_t)x)) - x;
|
||||
}
|
||||
|
||||
ATOMIC_INLINE uint64_t atomic_cas_uint64(uint64_t *v, uint64_t old, uint64_t _new)
|
||||
{
|
||||
return InterlockedCompareExchange64((int64_t *)v, _new, old);
|
||||
}
|
||||
|
||||
ATOMIC_INLINE uint64_t atomic_load_uint64(const uint64_t *v)
|
||||
{
|
||||
return __atomic_impl_load_generic(v);
|
||||
}
|
||||
|
||||
ATOMIC_INLINE void atomic_store_uint64(uint64_t *p, uint64_t v)
|
||||
{
|
||||
__atomic_impl_store_generic(p, v);
|
||||
}
|
||||
|
||||
ATOMIC_INLINE uint64_t atomic_fetch_and_add_uint64(uint64_t *p, uint64_t x)
|
||||
{
|
||||
return InterlockedExchangeAdd64((int64_t *)p, (int64_t)x);
|
||||
}
|
||||
|
||||
ATOMIC_INLINE uint64_t atomic_fetch_and_sub_uint64(uint64_t *p, uint64_t x)
|
||||
{
|
||||
return InterlockedExchangeAdd64((int64_t *)p, -((int64_t)x));
|
||||
}
|
||||
|
||||
/* Signed */
|
||||
ATOMIC_INLINE int64_t atomic_add_and_fetch_int64(int64_t *p, int64_t x)
|
||||
{
|
||||
return InterlockedExchangeAdd64(p, x) + x;
|
||||
}
|
||||
|
||||
ATOMIC_INLINE int64_t atomic_sub_and_fetch_int64(int64_t *p, int64_t x)
|
||||
{
|
||||
return InterlockedExchangeAdd64(p, -x) - x;
|
||||
}
|
||||
|
||||
ATOMIC_INLINE int64_t atomic_cas_int64(int64_t *v, int64_t old, int64_t _new)
|
||||
{
|
||||
return InterlockedCompareExchange64(v, _new, old);
|
||||
}
|
||||
|
||||
ATOMIC_INLINE int64_t atomic_load_int64(const int64_t *v)
|
||||
{
|
||||
return __atomic_impl_load_generic(v);
|
||||
}
|
||||
|
||||
ATOMIC_INLINE void atomic_store_int64(int64_t *p, int64_t v)
|
||||
{
|
||||
__atomic_impl_store_generic(p, v);
|
||||
}
|
||||
|
||||
ATOMIC_INLINE int64_t atomic_fetch_and_add_int64(int64_t *p, int64_t x)
|
||||
{
|
||||
return InterlockedExchangeAdd64(p, x);
|
||||
}
|
||||
|
||||
ATOMIC_INLINE int64_t atomic_fetch_and_sub_int64(int64_t *p, int64_t x)
|
||||
{
|
||||
return InterlockedExchangeAdd64(p, -x);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* 32-bit operations. */
|
||||
/* Unsigned */
|
||||
ATOMIC_INLINE uint32_t atomic_add_and_fetch_uint32(uint32_t *p, uint32_t x)
|
||||
{
|
||||
return InterlockedExchangeAdd(p, x) + x;
|
||||
}
|
||||
|
||||
ATOMIC_INLINE uint32_t atomic_sub_and_fetch_uint32(uint32_t *p, uint32_t x)
|
||||
{
|
||||
return InterlockedExchangeAdd(p, -((int32_t)x)) - x;
|
||||
}
|
||||
|
||||
ATOMIC_INLINE uint32_t atomic_cas_uint32(uint32_t *v, uint32_t old, uint32_t _new)
|
||||
{
|
||||
return InterlockedCompareExchange((long *)v, _new, old);
|
||||
}
|
||||
|
||||
ATOMIC_INLINE uint32_t atomic_load_uint32(const uint32_t *v)
|
||||
{
|
||||
return __atomic_impl_load_generic(v);
|
||||
}
|
||||
|
||||
ATOMIC_INLINE void atomic_store_uint32(uint32_t *p, uint32_t v)
|
||||
{
|
||||
__atomic_impl_store_generic(p, v);
|
||||
}
|
||||
|
||||
ATOMIC_INLINE uint32_t atomic_fetch_and_add_uint32(uint32_t *p, uint32_t x)
|
||||
{
|
||||
return InterlockedExchangeAdd(p, x);
|
||||
}
|
||||
|
||||
ATOMIC_INLINE uint32_t atomic_fetch_and_or_uint32(uint32_t *p, uint32_t x)
|
||||
{
|
||||
return InterlockedOr((long *)p, x);
|
||||
}
|
||||
|
||||
ATOMIC_INLINE uint32_t atomic_fetch_and_and_uint32(uint32_t *p, uint32_t x)
|
||||
{
|
||||
return InterlockedAnd((long *)p, x);
|
||||
}
|
||||
|
||||
/* Signed */
|
||||
ATOMIC_INLINE int32_t atomic_add_and_fetch_int32(int32_t *p, int32_t x)
|
||||
{
|
||||
return InterlockedExchangeAdd((long *)p, x) + x;
|
||||
}
|
||||
|
||||
ATOMIC_INLINE int32_t atomic_sub_and_fetch_int32(int32_t *p, int32_t x)
|
||||
{
|
||||
return InterlockedExchangeAdd((long *)p, -x) - x;
|
||||
}
|
||||
|
||||
ATOMIC_INLINE int32_t atomic_cas_int32(int32_t *v, int32_t old, int32_t _new)
|
||||
{
|
||||
return InterlockedCompareExchange((long *)v, _new, old);
|
||||
}
|
||||
|
||||
ATOMIC_INLINE int32_t atomic_load_int32(const int32_t *v)
|
||||
{
|
||||
return __atomic_impl_load_generic(v);
|
||||
}
|
||||
|
||||
ATOMIC_INLINE void atomic_store_int32(int32_t *p, int32_t v)
|
||||
{
|
||||
__atomic_impl_store_generic(p, v);
|
||||
}
|
||||
|
||||
ATOMIC_INLINE int32_t atomic_fetch_and_add_int32(int32_t *p, int32_t x)
|
||||
{
|
||||
return InterlockedExchangeAdd((long *)p, x);
|
||||
}
|
||||
|
||||
ATOMIC_INLINE int32_t atomic_fetch_and_or_int32(int32_t *p, int32_t x)
|
||||
{
|
||||
return InterlockedOr((long *)p, x);
|
||||
}
|
||||
|
||||
ATOMIC_INLINE int32_t atomic_fetch_and_and_int32(int32_t *p, int32_t x)
|
||||
{
|
||||
return InterlockedAnd((long *)p, x);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* 16-bit operations. */
|
||||
|
||||
/* Signed */
|
||||
ATOMIC_INLINE int16_t atomic_fetch_and_or_int16(int16_t *p, int16_t x)
|
||||
{
|
||||
return InterlockedOr16((short *)p, x);
|
||||
}
|
||||
|
||||
ATOMIC_INLINE int16_t atomic_fetch_and_and_int16(int16_t *p, int16_t x)
|
||||
{
|
||||
return InterlockedAnd16((short *)p, x);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* 8-bit operations. */
|
||||
|
||||
/* Unsigned */
|
||||
#pragma intrinsic(_InterlockedAnd8)
|
||||
ATOMIC_INLINE uint8_t atomic_fetch_and_and_uint8(uint8_t *p, uint8_t b)
|
||||
{
|
||||
#if (LG_SIZEOF_PTR == 8 || LG_SIZEOF_INT == 8)
|
||||
return InterlockedAnd8((char *)p, (char)b);
|
||||
#else
|
||||
return _InterlockedAnd8((char *)p, (char)b);
|
||||
#endif
|
||||
}
|
||||
|
||||
#pragma intrinsic(_InterlockedOr8)
|
||||
ATOMIC_INLINE uint8_t atomic_fetch_and_or_uint8(uint8_t *p, uint8_t b)
|
||||
{
|
||||
#if (LG_SIZEOF_PTR == 8 || LG_SIZEOF_INT == 8)
|
||||
return InterlockedOr8((char *)p, (char)b);
|
||||
#else
|
||||
return _InterlockedOr8((char *)p, (char)b);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Signed */
|
||||
#pragma intrinsic(_InterlockedAnd8)
|
||||
ATOMIC_INLINE int8_t atomic_fetch_and_and_int8(int8_t *p, int8_t b)
|
||||
{
|
||||
#if (LG_SIZEOF_PTR == 8 || LG_SIZEOF_INT == 8)
|
||||
return InterlockedAnd8((char *)p, (char)b);
|
||||
#else
|
||||
return _InterlockedAnd8((char *)p, (char)b);
|
||||
#endif
|
||||
}
|
||||
|
||||
#pragma intrinsic(_InterlockedOr8)
|
||||
ATOMIC_INLINE int8_t atomic_fetch_and_or_int8(int8_t *p, int8_t b)
|
||||
{
|
||||
#if (LG_SIZEOF_PTR == 8 || LG_SIZEOF_INT == 8)
|
||||
return InterlockedOr8((char *)p, (char)b);
|
||||
#else
|
||||
return _InterlockedOr8((char *)p, (char)b);
|
||||
#endif
|
||||
}
|
||||
|
||||
#undef __atomic_impl_load_generic
|
||||
#undef __atomic_impl_store_generic
|
||||
|
||||
#if defined(__clang__)
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif /* __ATOMIC_OPS_MSVC_H__ */
|
||||
690
blender-5.2.0/intern/atomic/intern/atomic_ops_unix.h
Normal file
690
blender-5.2.0/intern/atomic/intern/atomic_ops_unix.h
Normal file
@@ -0,0 +1,690 @@
|
||||
/*
|
||||
* Original code from jemalloc with this license:
|
||||
*
|
||||
* Copyright (C) 2002-2013 Jason Evans <jasone@canonware.com>.
|
||||
* All rights reserved.
|
||||
* Copyright (C) 2007-2012 Mozilla Foundation. All rights reserved.
|
||||
* Copyright (C) 2009-2013 Facebook, Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice(s),
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice(s),
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is adapted from jemalloc.
|
||||
* Modifications Copyright (C) 2016 Blender Foundation
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup intern_atomic
|
||||
*/
|
||||
|
||||
#ifndef __ATOMIC_OPS_UNIX_H__
|
||||
#define __ATOMIC_OPS_UNIX_H__
|
||||
|
||||
#include "atomic_ops_utils.h"
|
||||
|
||||
#if defined(__arm__) || defined(__riscv)
|
||||
/* Attempt to fix compilation error on Debian armel and RISC-V kernels.
|
||||
* Both architectures do have both 32 and 64bit atomics, however
|
||||
* its gcc doesn't have __GCC_HAVE_SYNC_COMPARE_AND_SWAP_n defined.
|
||||
*/
|
||||
# define JE_FORCE_SYNC_COMPARE_AND_SWAP_1
|
||||
# define JE_FORCE_SYNC_COMPARE_AND_SWAP_2
|
||||
# define JE_FORCE_SYNC_COMPARE_AND_SWAP_4
|
||||
# define JE_FORCE_SYNC_COMPARE_AND_SWAP_8
|
||||
#endif
|
||||
|
||||
/* Define the `ATOMIC_FORCE_USE_FALLBACK` to force lock-based fallback implementation to be used
|
||||
* (even on platforms where there is native implementation available via compiler.
|
||||
* Useful for development purposes. */
|
||||
#undef ATOMIC_FORCE_USE_FALLBACK
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Spin-lock implementation
|
||||
*
|
||||
* Used to implement atomics on unsupported platforms.
|
||||
* The spin implementation is shared for all platforms to make sure it compiles and tested.
|
||||
* \{ */
|
||||
|
||||
typedef struct AtomicSpinLock {
|
||||
volatile int lock;
|
||||
|
||||
/* Pad the structure size to a cache-line, to avoid unwanted sharing with other data. */
|
||||
int pad[32 - sizeof(int)];
|
||||
} __attribute__((aligned(32))) AtomicSpinLock;
|
||||
|
||||
ATOMIC_INLINE void atomic_spin_lock(volatile AtomicSpinLock *lock)
|
||||
{
|
||||
while (__sync_lock_test_and_set(&lock->lock, 1)) {
|
||||
while (lock->lock) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ATOMIC_INLINE void atomic_spin_unlock(volatile AtomicSpinLock *lock)
|
||||
{
|
||||
__sync_lock_release(&lock->lock);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Common part of x64 implementation
|
||||
* \{ */
|
||||
|
||||
/* TODO(sergey): On x64 platform both read and write of a variable aligned to its type size is
|
||||
* atomic, so in theory it is possible to avoid memory barrier and gain performance. The downside
|
||||
* of that would be that it will impose requirement to value which is being operated on. */
|
||||
#define __atomic_impl_load_generic(v) (__sync_synchronize(), *(v))
|
||||
#define __atomic_impl_store_generic(p, v) \
|
||||
do { \
|
||||
*(p) = (v); \
|
||||
__sync_synchronize(); \
|
||||
} while (0)
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Common part of locking fallback implementation
|
||||
* \{ */
|
||||
|
||||
/* Global lock, shared by all atomic operations implementations.
|
||||
*
|
||||
* Could be split into per-size locks, although added complexity and being more error-proone does
|
||||
* not seem to worth it for a fall-back implementation. */
|
||||
static _ATOMIC_MAYBE_UNUSED AtomicSpinLock _atomic_global_lock = {0};
|
||||
|
||||
#define ATOMIC_LOCKING_OP_AND_FETCH_DEFINE(_type, _op_name, _op) \
|
||||
ATOMIC_INLINE _type##_t atomic_##_op_name##_and_fetch_##_type(_type##_t *p, _type##_t x) \
|
||||
{ \
|
||||
atomic_spin_lock(&_atomic_global_lock); \
|
||||
const _type##_t original_value = *(p); \
|
||||
const _type##_t new_value = original_value _op(x); \
|
||||
*(p) = new_value; \
|
||||
atomic_spin_unlock(&_atomic_global_lock); \
|
||||
return new_value; \
|
||||
}
|
||||
|
||||
#define ATOMIC_LOCKING_FETCH_AND_OP_DEFINE(_type, _op_name, _op) \
|
||||
ATOMIC_INLINE _type##_t atomic_fetch_and_##_op_name##_##_type(_type##_t *p, _type##_t x) \
|
||||
{ \
|
||||
atomic_spin_lock(&_atomic_global_lock); \
|
||||
const _type##_t original_value = *(p); \
|
||||
*(p) = original_value _op(x); \
|
||||
atomic_spin_unlock(&_atomic_global_lock); \
|
||||
return original_value; \
|
||||
}
|
||||
|
||||
#define ATOMIC_LOCKING_ADD_AND_FETCH_DEFINE(_type) \
|
||||
ATOMIC_LOCKING_OP_AND_FETCH_DEFINE(_type, add, +)
|
||||
|
||||
#define ATOMIC_LOCKING_SUB_AND_FETCH_DEFINE(_type) \
|
||||
ATOMIC_LOCKING_OP_AND_FETCH_DEFINE(_type, sub, -)
|
||||
|
||||
#define ATOMIC_LOCKING_FETCH_AND_ADD_DEFINE(_type) \
|
||||
ATOMIC_LOCKING_FETCH_AND_OP_DEFINE(_type, add, +)
|
||||
|
||||
#define ATOMIC_LOCKING_FETCH_AND_SUB_DEFINE(_type) \
|
||||
ATOMIC_LOCKING_FETCH_AND_OP_DEFINE(_type, sub, -)
|
||||
|
||||
#define ATOMIC_LOCKING_FETCH_AND_OR_DEFINE(_type) ATOMIC_LOCKING_FETCH_AND_OP_DEFINE(_type, or, |)
|
||||
|
||||
#define ATOMIC_LOCKING_FETCH_AND_AND_DEFINE(_type) \
|
||||
ATOMIC_LOCKING_FETCH_AND_OP_DEFINE(_type, and, &)
|
||||
|
||||
#define ATOMIC_LOCKING_CAS_DEFINE(_type) \
|
||||
ATOMIC_INLINE _type##_t atomic_cas_##_type(_type##_t *v, _type##_t old, _type##_t _new) \
|
||||
{ \
|
||||
atomic_spin_lock(&_atomic_global_lock); \
|
||||
const _type##_t original_value = *v; \
|
||||
if (*v == old) { \
|
||||
*v = _new; \
|
||||
} \
|
||||
atomic_spin_unlock(&_atomic_global_lock); \
|
||||
return original_value; \
|
||||
}
|
||||
|
||||
#define ATOMIC_LOCKING_LOAD_DEFINE(_type) \
|
||||
ATOMIC_INLINE _type##_t atomic_load_##_type(const _type##_t *v) \
|
||||
{ \
|
||||
atomic_spin_lock(&_atomic_global_lock); \
|
||||
const _type##_t value = *v; \
|
||||
atomic_spin_unlock(&_atomic_global_lock); \
|
||||
return value; \
|
||||
}
|
||||
|
||||
#define ATOMIC_LOCKING_STORE_DEFINE(_type) \
|
||||
ATOMIC_INLINE void atomic_store_##_type(_type##_t *p, const _type##_t v) \
|
||||
{ \
|
||||
atomic_spin_lock(&_atomic_global_lock); \
|
||||
*p = v; \
|
||||
atomic_spin_unlock(&_atomic_global_lock); \
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name 64-bit operations
|
||||
* \{ */
|
||||
|
||||
#if !defined(ATOMIC_FORCE_USE_FALLBACK) && \
|
||||
(defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8) || defined(JE_FORCE_SYNC_COMPARE_AND_SWAP_8))
|
||||
/* Unsigned */
|
||||
ATOMIC_INLINE uint64_t atomic_add_and_fetch_uint64(uint64_t *p, uint64_t x)
|
||||
{
|
||||
return __sync_add_and_fetch(p, x);
|
||||
}
|
||||
|
||||
ATOMIC_INLINE uint64_t atomic_sub_and_fetch_uint64(uint64_t *p, uint64_t x)
|
||||
{
|
||||
return __sync_sub_and_fetch(p, x);
|
||||
}
|
||||
|
||||
ATOMIC_INLINE uint64_t atomic_fetch_and_add_uint64(uint64_t *p, uint64_t x)
|
||||
{
|
||||
return __sync_fetch_and_add(p, x);
|
||||
}
|
||||
|
||||
ATOMIC_INLINE uint64_t atomic_fetch_and_sub_uint64(uint64_t *p, uint64_t x)
|
||||
{
|
||||
return __sync_fetch_and_sub(p, x);
|
||||
}
|
||||
|
||||
ATOMIC_INLINE uint64_t atomic_cas_uint64(uint64_t *v, uint64_t old, uint64_t _new)
|
||||
{
|
||||
return __sync_val_compare_and_swap(v, old, _new);
|
||||
}
|
||||
|
||||
ATOMIC_INLINE uint64_t atomic_load_uint64(const uint64_t *v)
|
||||
{
|
||||
return __atomic_load_n(v, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
ATOMIC_INLINE void atomic_store_uint64(uint64_t *p, uint64_t v)
|
||||
{
|
||||
__atomic_store(p, &v, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
/* Signed */
|
||||
ATOMIC_INLINE int64_t atomic_add_and_fetch_int64(int64_t *p, int64_t x)
|
||||
{
|
||||
return __sync_add_and_fetch(p, x);
|
||||
}
|
||||
|
||||
ATOMIC_INLINE int64_t atomic_sub_and_fetch_int64(int64_t *p, int64_t x)
|
||||
{
|
||||
return __sync_sub_and_fetch(p, x);
|
||||
}
|
||||
|
||||
ATOMIC_INLINE int64_t atomic_fetch_and_add_int64(int64_t *p, int64_t x)
|
||||
{
|
||||
return __sync_fetch_and_add(p, x);
|
||||
}
|
||||
|
||||
ATOMIC_INLINE int64_t atomic_fetch_and_sub_int64(int64_t *p, int64_t x)
|
||||
{
|
||||
return __sync_fetch_and_sub(p, x);
|
||||
}
|
||||
|
||||
ATOMIC_INLINE int64_t atomic_cas_int64(int64_t *v, int64_t old, int64_t _new)
|
||||
{
|
||||
return __sync_val_compare_and_swap(v, old, _new);
|
||||
}
|
||||
|
||||
ATOMIC_INLINE int64_t atomic_load_int64(const int64_t *v)
|
||||
{
|
||||
return __atomic_load_n(v, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
ATOMIC_INLINE void atomic_store_int64(int64_t *p, int64_t v)
|
||||
{
|
||||
__atomic_store(p, &v, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
#elif !defined(ATOMIC_FORCE_USE_FALLBACK) && (defined(__amd64__) || defined(__x86_64__))
|
||||
/* Unsigned */
|
||||
ATOMIC_INLINE uint64_t atomic_fetch_and_add_uint64(uint64_t *p, uint64_t x)
|
||||
{
|
||||
asm volatile("lock; xaddq %0, %1;"
|
||||
: "+r"(x), "=m"(*p) /* Outputs. */
|
||||
: "m"(*p) /* Inputs. */
|
||||
);
|
||||
return x;
|
||||
}
|
||||
|
||||
ATOMIC_INLINE uint64_t atomic_fetch_and_sub_uint64(uint64_t *p, uint64_t x)
|
||||
{
|
||||
x = (uint64_t)(-(int64_t)x);
|
||||
asm volatile("lock; xaddq %0, %1;"
|
||||
: "+r"(x), "=m"(*p) /* Outputs. */
|
||||
: "m"(*p) /* Inputs. */
|
||||
);
|
||||
return x;
|
||||
}
|
||||
|
||||
ATOMIC_INLINE uint64_t atomic_add_and_fetch_uint64(uint64_t *p, uint64_t x)
|
||||
{
|
||||
return atomic_fetch_and_add_uint64(p, x) + x;
|
||||
}
|
||||
|
||||
ATOMIC_INLINE uint64_t atomic_sub_and_fetch_uint64(uint64_t *p, uint64_t x)
|
||||
{
|
||||
return atomic_fetch_and_sub_uint64(p, x) - x;
|
||||
}
|
||||
|
||||
ATOMIC_INLINE uint64_t atomic_cas_uint64(uint64_t *v, uint64_t old, uint64_t _new)
|
||||
{
|
||||
uint64_t ret;
|
||||
asm volatile("lock; cmpxchgq %2,%1" : "=a"(ret), "+m"(*v) : "r"(_new), "0"(old) : "memory");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ATOMIC_INLINE uint64_t atomic_load_uint64(const uint64_t *v)
|
||||
{
|
||||
return __atomic_impl_load_generic(v);
|
||||
}
|
||||
|
||||
ATOMIC_INLINE void atomic_store_uint64(uint64_t *p, uint64_t v)
|
||||
{
|
||||
__atomic_impl_store_generic(p, v);
|
||||
}
|
||||
|
||||
/* Signed */
|
||||
ATOMIC_INLINE int64_t atomic_fetch_and_add_int64(int64_t *p, int64_t x)
|
||||
{
|
||||
asm volatile("lock; xaddq %0, %1;"
|
||||
: "+r"(x), "=m"(*p) /* Outputs. */
|
||||
: "m"(*p) /* Inputs. */
|
||||
);
|
||||
return x;
|
||||
}
|
||||
|
||||
ATOMIC_INLINE int64_t atomic_fetch_and_sub_int64(int64_t *p, int64_t x)
|
||||
{
|
||||
x = -x;
|
||||
asm volatile("lock; xaddq %0, %1;"
|
||||
: "+r"(x), "=m"(*p) /* Outputs. */
|
||||
: "m"(*p) /* Inputs. */
|
||||
);
|
||||
return x;
|
||||
}
|
||||
|
||||
ATOMIC_INLINE int64_t atomic_add_and_fetch_int64(int64_t *p, int64_t x)
|
||||
{
|
||||
return atomic_fetch_and_add_int64(p, x) + x;
|
||||
}
|
||||
|
||||
ATOMIC_INLINE int64_t atomic_sub_and_fetch_int64(int64_t *p, int64_t x)
|
||||
{
|
||||
return atomic_fetch_and_sub_int64(p, x) - x;
|
||||
}
|
||||
|
||||
ATOMIC_INLINE int64_t atomic_cas_int64(int64_t *v, int64_t old, int64_t _new)
|
||||
{
|
||||
int64_t ret;
|
||||
asm volatile("lock; cmpxchgq %2,%1" : "=a"(ret), "+m"(*v) : "r"(_new), "0"(old) : "memory");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ATOMIC_INLINE int64_t atomic_load_int64(const int64_t *v)
|
||||
{
|
||||
return __atomic_impl_load_generic(v);
|
||||
}
|
||||
|
||||
ATOMIC_INLINE void atomic_store_int64(int64_t *p, int64_t v)
|
||||
{
|
||||
__atomic_impl_store_generic(p, v);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Unsigned */
|
||||
|
||||
ATOMIC_LOCKING_ADD_AND_FETCH_DEFINE(uint64)
|
||||
ATOMIC_LOCKING_SUB_AND_FETCH_DEFINE(uint64)
|
||||
|
||||
ATOMIC_LOCKING_FETCH_AND_ADD_DEFINE(uint64)
|
||||
ATOMIC_LOCKING_FETCH_AND_SUB_DEFINE(uint64)
|
||||
|
||||
ATOMIC_LOCKING_CAS_DEFINE(uint64)
|
||||
|
||||
ATOMIC_LOCKING_LOAD_DEFINE(uint64)
|
||||
ATOMIC_LOCKING_STORE_DEFINE(uint64)
|
||||
|
||||
/* Signed */
|
||||
ATOMIC_LOCKING_ADD_AND_FETCH_DEFINE(int64)
|
||||
ATOMIC_LOCKING_SUB_AND_FETCH_DEFINE(int64)
|
||||
|
||||
ATOMIC_LOCKING_FETCH_AND_ADD_DEFINE(int64)
|
||||
ATOMIC_LOCKING_FETCH_AND_SUB_DEFINE(int64)
|
||||
|
||||
ATOMIC_LOCKING_CAS_DEFINE(int64)
|
||||
|
||||
ATOMIC_LOCKING_LOAD_DEFINE(int64)
|
||||
ATOMIC_LOCKING_STORE_DEFINE(int64)
|
||||
|
||||
#endif
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name 32-bit operations
|
||||
* \{ */
|
||||
|
||||
#if !defined(ATOMIC_FORCE_USE_FALLBACK) && \
|
||||
(defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) || defined(JE_FORCE_SYNC_COMPARE_AND_SWAP_4))
|
||||
/* Unsigned */
|
||||
ATOMIC_INLINE uint32_t atomic_add_and_fetch_uint32(uint32_t *p, uint32_t x)
|
||||
{
|
||||
return __sync_add_and_fetch(p, x);
|
||||
}
|
||||
|
||||
ATOMIC_INLINE uint32_t atomic_sub_and_fetch_uint32(uint32_t *p, uint32_t x)
|
||||
{
|
||||
return __sync_sub_and_fetch(p, x);
|
||||
}
|
||||
|
||||
ATOMIC_INLINE uint32_t atomic_cas_uint32(uint32_t *v, uint32_t old, uint32_t _new)
|
||||
{
|
||||
return __sync_val_compare_and_swap(v, old, _new);
|
||||
}
|
||||
|
||||
ATOMIC_INLINE uint32_t atomic_load_uint32(const uint32_t *v)
|
||||
{
|
||||
return __atomic_load_n(v, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
ATOMIC_INLINE void atomic_store_uint32(uint32_t *p, uint32_t v)
|
||||
{
|
||||
__atomic_store(p, &v, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
/* Signed */
|
||||
ATOMIC_INLINE int32_t atomic_add_and_fetch_int32(int32_t *p, int32_t x)
|
||||
{
|
||||
return __sync_add_and_fetch(p, x);
|
||||
}
|
||||
|
||||
ATOMIC_INLINE int32_t atomic_sub_and_fetch_int32(int32_t *p, int32_t x)
|
||||
{
|
||||
return __sync_sub_and_fetch(p, x);
|
||||
}
|
||||
|
||||
ATOMIC_INLINE int32_t atomic_cas_int32(int32_t *v, int32_t old, int32_t _new)
|
||||
{
|
||||
return __sync_val_compare_and_swap(v, old, _new);
|
||||
}
|
||||
|
||||
ATOMIC_INLINE int32_t atomic_load_int32(const int32_t *v)
|
||||
{
|
||||
return __atomic_load_n(v, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
ATOMIC_INLINE void atomic_store_int32(int32_t *p, int32_t v)
|
||||
{
|
||||
__atomic_store(p, &v, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
#elif !defined(ATOMIC_FORCE_USE_FALLBACK) && \
|
||||
(defined(__i386__) || defined(__amd64__) || defined(__x86_64__))
|
||||
/* Unsigned */
|
||||
ATOMIC_INLINE uint32_t atomic_add_and_fetch_uint32(uint32_t *p, uint32_t x)
|
||||
{
|
||||
uint32_t ret = x;
|
||||
asm volatile("lock; xaddl %0, %1;"
|
||||
: "+r"(ret), "=m"(*p) /* Outputs. */
|
||||
: "m"(*p) /* Inputs. */
|
||||
);
|
||||
return ret + x;
|
||||
}
|
||||
|
||||
ATOMIC_INLINE uint32_t atomic_sub_and_fetch_uint32(uint32_t *p, uint32_t x)
|
||||
{
|
||||
uint32_t ret = (uint32_t)(-(int32_t)x);
|
||||
asm volatile("lock; xaddl %0, %1;"
|
||||
: "+r"(ret), "=m"(*p) /* Outputs. */
|
||||
: "m"(*p) /* Inputs. */
|
||||
);
|
||||
return ret - x;
|
||||
}
|
||||
|
||||
ATOMIC_INLINE uint32_t atomic_cas_uint32(uint32_t *v, uint32_t old, uint32_t _new)
|
||||
{
|
||||
uint32_t ret;
|
||||
asm volatile("lock; cmpxchgl %2,%1" : "=a"(ret), "+m"(*v) : "r"(_new), "0"(old) : "memory");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ATOMIC_INLINE uint32_t atomic_load_uint32(const uint32_t *v)
|
||||
{
|
||||
return __atomic_load_n(v, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
ATOMIC_INLINE void atomic_store_uint32(uint32_t *p, uint32_t v)
|
||||
{
|
||||
__atomic_store(p, &v, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
/* Signed */
|
||||
ATOMIC_INLINE int32_t atomic_add_and_fetch_int32(int32_t *p, int32_t x)
|
||||
{
|
||||
int32_t ret = x;
|
||||
asm volatile("lock; xaddl %0, %1;"
|
||||
: "+r"(ret), "=m"(*p) /* Outputs. */
|
||||
: "m"(*p) /* Inputs. */
|
||||
);
|
||||
return ret + x;
|
||||
}
|
||||
|
||||
ATOMIC_INLINE int32_t atomic_sub_and_fetch_int32(int32_t *p, int32_t x)
|
||||
{
|
||||
int32_t ret = -x;
|
||||
asm volatile("lock; xaddl %0, %1;"
|
||||
: "+r"(ret), "=m"(*p) /* Outputs. */
|
||||
: "m"(*p) /* Inputs. */
|
||||
);
|
||||
return ret - x;
|
||||
}
|
||||
|
||||
ATOMIC_INLINE int32_t atomic_cas_int32(int32_t *v, int32_t old, int32_t _new)
|
||||
{
|
||||
int32_t ret;
|
||||
asm volatile("lock; cmpxchgl %2,%1" : "=a"(ret), "+m"(*v) : "r"(_new), "0"(old) : "memory");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ATOMIC_INLINE int32_t atomic_load_int32(const int32_t *v)
|
||||
{
|
||||
return __atomic_load_n(v, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
ATOMIC_INLINE void atomic_store_int32(int32_t *p, int32_t v)
|
||||
{
|
||||
__atomic_store(p, &v, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Unsigned */
|
||||
|
||||
ATOMIC_LOCKING_ADD_AND_FETCH_DEFINE(uint32)
|
||||
ATOMIC_LOCKING_SUB_AND_FETCH_DEFINE(uint32)
|
||||
|
||||
ATOMIC_LOCKING_CAS_DEFINE(uint32)
|
||||
|
||||
ATOMIC_LOCKING_LOAD_DEFINE(uint32)
|
||||
ATOMIC_LOCKING_STORE_DEFINE(uint32)
|
||||
|
||||
/* Signed */
|
||||
|
||||
ATOMIC_LOCKING_ADD_AND_FETCH_DEFINE(int32)
|
||||
ATOMIC_LOCKING_SUB_AND_FETCH_DEFINE(int32)
|
||||
|
||||
ATOMIC_LOCKING_CAS_DEFINE(int32)
|
||||
|
||||
ATOMIC_LOCKING_LOAD_DEFINE(int32)
|
||||
ATOMIC_LOCKING_STORE_DEFINE(int32)
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(ATOMIC_FORCE_USE_FALLBACK) && \
|
||||
(defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) || defined(JE_FORCE_SYNC_COMPARE_AND_SWAP_4))
|
||||
/* Unsigned */
|
||||
ATOMIC_INLINE uint32_t atomic_fetch_and_add_uint32(uint32_t *p, uint32_t x)
|
||||
{
|
||||
return __sync_fetch_and_add(p, x);
|
||||
}
|
||||
|
||||
ATOMIC_INLINE uint32_t atomic_fetch_and_or_uint32(uint32_t *p, uint32_t x)
|
||||
{
|
||||
return __sync_fetch_and_or(p, x);
|
||||
}
|
||||
|
||||
ATOMIC_INLINE uint32_t atomic_fetch_and_and_uint32(uint32_t *p, uint32_t x)
|
||||
{
|
||||
return __sync_fetch_and_and(p, x);
|
||||
}
|
||||
|
||||
/* Signed */
|
||||
ATOMIC_INLINE int32_t atomic_fetch_and_add_int32(int32_t *p, int32_t x)
|
||||
{
|
||||
return __sync_fetch_and_add(p, x);
|
||||
}
|
||||
|
||||
ATOMIC_INLINE int32_t atomic_fetch_and_or_int32(int32_t *p, int32_t x)
|
||||
{
|
||||
return __sync_fetch_and_or(p, x);
|
||||
}
|
||||
|
||||
ATOMIC_INLINE int32_t atomic_fetch_and_and_int32(int32_t *p, int32_t x)
|
||||
{
|
||||
return __sync_fetch_and_and(p, x);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Unsigned */
|
||||
ATOMIC_LOCKING_FETCH_AND_ADD_DEFINE(uint32)
|
||||
ATOMIC_LOCKING_FETCH_AND_OR_DEFINE(uint32)
|
||||
ATOMIC_LOCKING_FETCH_AND_AND_DEFINE(uint32)
|
||||
|
||||
/* Signed */
|
||||
ATOMIC_LOCKING_FETCH_AND_ADD_DEFINE(int32)
|
||||
ATOMIC_LOCKING_FETCH_AND_OR_DEFINE(int32)
|
||||
ATOMIC_LOCKING_FETCH_AND_AND_DEFINE(int32)
|
||||
|
||||
#endif
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name 16-bit operations
|
||||
* \{ */
|
||||
|
||||
#if !defined(ATOMIC_FORCE_USE_FALLBACK) && \
|
||||
(defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2) || defined(JE_FORCE_SYNC_COMPARE_AND_SWAP_2))
|
||||
|
||||
/* Signed */
|
||||
ATOMIC_INLINE int16_t atomic_fetch_and_and_int16(int16_t *p, int16_t b)
|
||||
{
|
||||
return __sync_fetch_and_and(p, b);
|
||||
}
|
||||
ATOMIC_INLINE int16_t atomic_fetch_and_or_int16(int16_t *p, int16_t b)
|
||||
{
|
||||
return __sync_fetch_and_or(p, b);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
ATOMIC_LOCKING_FETCH_AND_AND_DEFINE(int16)
|
||||
ATOMIC_LOCKING_FETCH_AND_OR_DEFINE(int16)
|
||||
|
||||
#endif
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name 8-bit operations
|
||||
* \{ */
|
||||
|
||||
#if !defined(ATOMIC_FORCE_USE_FALLBACK) && \
|
||||
(defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1) || defined(JE_FORCE_SYNC_COMPARE_AND_SWAP_1))
|
||||
|
||||
/* Unsigned */
|
||||
ATOMIC_INLINE uint8_t atomic_fetch_and_and_uint8(uint8_t *p, uint8_t b)
|
||||
{
|
||||
return __sync_fetch_and_and(p, b);
|
||||
}
|
||||
ATOMIC_INLINE uint8_t atomic_fetch_and_or_uint8(uint8_t *p, uint8_t b)
|
||||
{
|
||||
return __sync_fetch_and_or(p, b);
|
||||
}
|
||||
|
||||
/* Signed */
|
||||
ATOMIC_INLINE int8_t atomic_fetch_and_and_int8(int8_t *p, int8_t b)
|
||||
{
|
||||
return __sync_fetch_and_and(p, b);
|
||||
}
|
||||
ATOMIC_INLINE int8_t atomic_fetch_and_or_int8(int8_t *p, int8_t b)
|
||||
{
|
||||
return __sync_fetch_and_or(p, b);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Unsigned */
|
||||
ATOMIC_LOCKING_FETCH_AND_AND_DEFINE(uint8)
|
||||
ATOMIC_LOCKING_FETCH_AND_OR_DEFINE(uint8)
|
||||
|
||||
/* Signed */
|
||||
ATOMIC_LOCKING_FETCH_AND_AND_DEFINE(int8)
|
||||
ATOMIC_LOCKING_FETCH_AND_OR_DEFINE(int8)
|
||||
|
||||
#endif
|
||||
|
||||
/** \} */
|
||||
|
||||
#undef __atomic_impl_load_generic
|
||||
#undef __atomic_impl_store_generic
|
||||
|
||||
#undef ATOMIC_LOCKING_OP_AND_FETCH_DEFINE
|
||||
#undef ATOMIC_LOCKING_FETCH_AND_OP_DEFINE
|
||||
#undef ATOMIC_LOCKING_ADD_AND_FETCH_DEFINE
|
||||
#undef ATOMIC_LOCKING_SUB_AND_FETCH_DEFINE
|
||||
#undef ATOMIC_LOCKING_FETCH_AND_ADD_DEFINE
|
||||
#undef ATOMIC_LOCKING_FETCH_AND_SUB_DEFINE
|
||||
#undef ATOMIC_LOCKING_FETCH_AND_OR_DEFINE
|
||||
#undef ATOMIC_LOCKING_FETCH_AND_AND_DEFINE
|
||||
#undef ATOMIC_LOCKING_CAS_DEFINE
|
||||
#undef ATOMIC_LOCKING_LOAD_DEFINE
|
||||
#undef ATOMIC_LOCKING_STORE_DEFINE
|
||||
|
||||
#endif /* __ATOMIC_OPS_UNIX_H__ */
|
||||
131
blender-5.2.0/intern/atomic/intern/atomic_ops_utils.h
Normal file
131
blender-5.2.0/intern/atomic/intern/atomic_ops_utils.h
Normal file
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Original code from jemalloc with this license:
|
||||
*
|
||||
* Copyright (C) 2002-2013 Jason Evans <jasone@canonware.com>.
|
||||
* All rights reserved.
|
||||
* Copyright (C) 2007-2012 Mozilla Foundation. All rights reserved.
|
||||
* Copyright (C) 2009-2013 Facebook, Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice(s),
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice(s),
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is adapted from jemalloc.
|
||||
* Modifications Copyright (C) 2016 Blender Foundation
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup intern_atomic
|
||||
*/
|
||||
|
||||
#ifndef __ATOMIC_OPS_UTILS_H__
|
||||
#define __ATOMIC_OPS_UTILS_H__
|
||||
|
||||
#include <limits.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
/* little macro so inline keyword works */
|
||||
#if defined(_MSC_VER)
|
||||
# define ATOMIC_INLINE static __forceinline
|
||||
#else
|
||||
# define ATOMIC_INLINE static inline __attribute__((always_inline))
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
# define _ATOMIC_LIKELY(x) __builtin_expect(!!(x), 1)
|
||||
# define _ATOMIC_UNLIKELY(x) __builtin_expect(!!(x), 0)
|
||||
# define _ATOMIC_MAYBE_UNUSED __attribute__((unused))
|
||||
#else
|
||||
# define _ATOMIC_LIKELY(x) (x)
|
||||
# define _ATOMIC_UNLIKELY(x) (x)
|
||||
# define _ATOMIC_MAYBE_UNUSED
|
||||
#endif
|
||||
|
||||
#if defined(__SIZEOF_POINTER__)
|
||||
# define LG_SIZEOF_PTR __SIZEOF_POINTER__
|
||||
#elif defined(UINTPTR_MAX)
|
||||
# if (UINTPTR_MAX == 0xFFFFFFFF)
|
||||
# define LG_SIZEOF_PTR 4
|
||||
# elif (UINTPTR_MAX == 0xFFFFFFFFFFFFFFFF)
|
||||
# define LG_SIZEOF_PTR 8
|
||||
# endif
|
||||
#elif defined(__WORDSIZE) /* Fallback for older glibc and cpp */
|
||||
# if (__WORDSIZE == 32)
|
||||
# define LG_SIZEOF_PTR 4
|
||||
# elif (__WORDSIZE == 64)
|
||||
# define LG_SIZEOF_PTR 8
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef LG_SIZEOF_PTR
|
||||
# error "Cannot find pointer size"
|
||||
#endif
|
||||
|
||||
#if (UINT_MAX == 0xFFFFFFFF)
|
||||
# define LG_SIZEOF_INT 4
|
||||
#elif (UINT_MAX == 0xFFFFFFFFFFFFFFFF)
|
||||
# define LG_SIZEOF_INT 8
|
||||
#else
|
||||
# error "Cannot find int size"
|
||||
#endif
|
||||
|
||||
/* Copied from BLI_utils... */
|
||||
/* C++ can't use _Static_assert, expects static_assert() but c++0x only,
|
||||
* Coverity also errors out. */
|
||||
#if (!defined(__cplusplus)) && (!defined(__COVERITY__)) && (defined(__GNUC__)) /* GCC only. */
|
||||
# define ATOMIC_STATIC_ASSERT(a, msg) __extension__ _Static_assert(a, msg);
|
||||
#else
|
||||
/* Code adapted from http://www.pixelbeat.org/programming/gcc/static_assert.html */
|
||||
/* Note we need the two concats below because arguments to ## are not expanded, so we need to
|
||||
* expand __LINE__ with one indirection before doing the actual concatenation. */
|
||||
# define ATOMIC_ASSERT_CONCAT_(a, b) a##b
|
||||
# define ATOMIC_ASSERT_CONCAT(a, b) ATOMIC_ASSERT_CONCAT_(a, b)
|
||||
/* These can't be used after statements in c89. */
|
||||
# if defined(__COUNTER__) /* MSVC */
|
||||
# define ATOMIC_STATIC_ASSERT(a, msg) \
|
||||
; \
|
||||
enum { ATOMIC_ASSERT_CONCAT(static_assert_, __COUNTER__) = 1 / (int)(!!(a)) };
|
||||
# else /* older gcc, clang... */
|
||||
/* This can't be used twice on the same line so ensure if using in headers
|
||||
* that the headers are not included twice (by wrapping in #ifndef...#endif)
|
||||
* Note it doesn't cause an issue when used on same line of separate modules
|
||||
* compiled with gcc -combine -fwhole-program. */
|
||||
# define ATOMIC_STATIC_ASSERT(a, msg) \
|
||||
; \
|
||||
enum { ATOMIC_ASSERT_CONCAT(assert_line_, __LINE__) = 1 / (int)(!!(a)) };
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif /* __ATOMIC_OPS_UTILS_H__ */
|
||||
1104
blender-5.2.0/intern/atomic/tests/atomic_test.cc
Normal file
1104
blender-5.2.0/intern/atomic/tests/atomic_test.cc
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user