200 lines
4.9 KiB
C
200 lines
4.9 KiB
C
/*
|
|
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
|
*
|
|
* This program is free software: you can use, redistribute, and/or modify
|
|
* it under the terms of the GNU Affero General Public License, version 3
|
|
* or later ("AGPL"), as published by the Free Software Foundation.
|
|
*
|
|
* 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.
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "os.h"
|
|
|
|
#if defined(_TD_WINDOWS_64) || defined(_TD_WINDOWS_32)
|
|
|
|
// add
|
|
char interlocked_add_fetch_8(char volatile* ptr, char val) {
|
|
#ifdef _TD_GO_DLL_
|
|
return __sync_fetch_and_add(ptr, val) + val;
|
|
#else
|
|
return _InterlockedExchangeAdd8(ptr, val) + val;
|
|
#endif
|
|
}
|
|
|
|
short interlocked_add_fetch_16(short volatile* ptr, short val) {
|
|
#ifdef _TD_GO_DLL_
|
|
return __sync_fetch_and_add(ptr, val) + val;
|
|
#else
|
|
return _InterlockedExchangeAdd16(ptr, val) + val;
|
|
#endif
|
|
}
|
|
|
|
long interlocked_add_fetch_32(long volatile* ptr, long val) {
|
|
return _InterlockedExchangeAdd(ptr, val) + val;
|
|
}
|
|
|
|
__int64 interlocked_add_fetch_64(__int64 volatile* ptr, __int64 val) {
|
|
//#ifdef _WIN64
|
|
return InterlockedExchangeAdd64(ptr, val) + val;
|
|
//#else
|
|
// return _InterlockedExchangeAdd(ptr, val) + val;
|
|
//#endif
|
|
}
|
|
|
|
char interlocked_and_fetch_8(char volatile* ptr, char val) {
|
|
return _InterlockedAnd8(ptr, val) & val;
|
|
}
|
|
|
|
short interlocked_and_fetch_16(short volatile* ptr, short val) {
|
|
return _InterlockedAnd16(ptr, val) & val;
|
|
}
|
|
|
|
long interlocked_and_fetch_32(long volatile* ptr, long val) {
|
|
return _InterlockedAnd(ptr, val) & val;
|
|
}
|
|
|
|
|
|
__int64 interlocked_and_fetch_64(__int64 volatile* ptr, __int64 val) {
|
|
#ifndef _M_IX86
|
|
return _InterlockedAnd64(ptr, val) & val;
|
|
#else
|
|
__int64 old, res;
|
|
do {
|
|
old = *ptr;
|
|
res = old & val;
|
|
} while (_InterlockedCompareExchange64(ptr, res, old) != old);
|
|
return res;
|
|
#endif
|
|
}
|
|
|
|
__int64 interlocked_fetch_and_64(__int64 volatile* ptr, __int64 val) {
|
|
#ifdef _M_IX86
|
|
__int64 old;
|
|
do {
|
|
old = *ptr;
|
|
} while (_InterlockedCompareExchange64(ptr, old & val, old) != old);
|
|
return old;
|
|
#else
|
|
return _InterlockedAnd64((__int64 volatile*)(ptr), (__int64)(val));
|
|
#endif
|
|
}
|
|
|
|
char interlocked_or_fetch_8(char volatile* ptr, char val) {
|
|
return _InterlockedOr8(ptr, val) | val;
|
|
}
|
|
|
|
short interlocked_or_fetch_16(short volatile* ptr, short val) {
|
|
return _InterlockedOr16(ptr, val) | val;
|
|
}
|
|
|
|
long interlocked_or_fetch_32(long volatile* ptr, long val) {
|
|
return _InterlockedOr(ptr, val) | val;
|
|
}
|
|
|
|
__int64 interlocked_or_fetch_64(__int64 volatile* ptr, __int64 val) {
|
|
#ifdef _M_IX86
|
|
__int64 old, res;
|
|
do {
|
|
old = *ptr;
|
|
res = old | val;
|
|
} while(_InterlockedCompareExchange64(ptr, res, old) != old);
|
|
return res;
|
|
#else
|
|
return _InterlockedOr64(ptr, val) & val;
|
|
#endif
|
|
}
|
|
|
|
__int64 interlocked_fetch_or_64(__int64 volatile* ptr, __int64 val) {
|
|
#ifdef _M_IX86
|
|
__int64 old;
|
|
do {
|
|
old = *ptr;
|
|
} while(_InterlockedCompareExchange64(ptr, old | val, old) != old);
|
|
return old;
|
|
#else
|
|
return _InterlockedOr64((__int64 volatile*)(ptr), (__int64)(val));
|
|
#endif
|
|
}
|
|
|
|
char interlocked_xor_fetch_8(char volatile* ptr, char val) {
|
|
return _InterlockedXor8(ptr, val) ^ val;
|
|
}
|
|
|
|
short interlocked_xor_fetch_16(short volatile* ptr, short val) {
|
|
return _InterlockedXor16(ptr, val) ^ val;
|
|
}
|
|
|
|
long interlocked_xor_fetch_32(long volatile* ptr, long val) {
|
|
return _InterlockedXor(ptr, val) ^ val;
|
|
}
|
|
|
|
__int64 interlocked_xor_fetch_64(__int64 volatile* ptr, __int64 val) {
|
|
#ifdef _M_IX86
|
|
__int64 old, res;
|
|
do {
|
|
old = *ptr;
|
|
res = old ^ val;
|
|
} while(_InterlockedCompareExchange64(ptr, res, old) != old);
|
|
return res;
|
|
#else
|
|
return _InterlockedXor64(ptr, val) ^ val;
|
|
#endif
|
|
}
|
|
|
|
__int64 interlocked_fetch_xor_64(__int64 volatile* ptr, __int64 val) {
|
|
#ifdef _M_IX86
|
|
__int64 old;
|
|
do {
|
|
old = *ptr;
|
|
} while (_InterlockedCompareExchange64(ptr, old ^ val, old) != old);
|
|
return old;
|
|
#else
|
|
return _InterlockedXor64((__int64 volatile*)(ptr), (__int64)(val));
|
|
#endif
|
|
}
|
|
|
|
#endif
|
|
|
|
#ifdef _TD_NINGSI_60
|
|
void* atomic_exchange_ptr_impl(void** ptr, void* val ) {
|
|
void *old;
|
|
do {
|
|
old = *ptr;
|
|
} while( !__sync_bool_compare_and_swap(ptr, old, val) );
|
|
return old;
|
|
}
|
|
int8_t atomic_exchange_8_impl(int8_t* ptr, int8_t val ) {
|
|
int8_t old;
|
|
do {
|
|
old = *ptr;
|
|
} while( !__sync_bool_compare_and_swap(ptr, old, val) );
|
|
return old;
|
|
}
|
|
int16_t atomic_exchange_16_impl(int16_t* ptr, int16_t val ) {
|
|
int16_t old;
|
|
do {
|
|
old = *ptr;
|
|
} while( !__sync_bool_compare_and_swap(ptr, old, val) );
|
|
return old;
|
|
}
|
|
int32_t atomic_exchange_32_impl(int32_t* ptr, int32_t val ) {
|
|
int32_t old;
|
|
do {
|
|
old = *ptr;
|
|
} while( !__sync_bool_compare_and_swap(ptr, old, val) );
|
|
return old;
|
|
}
|
|
int64_t atomic_exchange_64_impl(int64_t* ptr, int64_t val ) {
|
|
int64_t old;
|
|
do {
|
|
old = *ptr;
|
|
} while( !__sync_bool_compare_and_swap(ptr, old, val) );
|
|
return old;
|
|
}
|
|
#endif
|