Tissue Forge C++ 0.2.1
Interactive, particle-based physics, chemistry and biology modeling and simulation environment
Loading...
Searching...
No Matches
tf_lock.h
1/*******************************************************************************
2 * This file is part of mdcore.
3 * Coypright (c) 2012 Pedro Gonnet (pedro.gonnet@durham.ac.uk)
4 * Coypright (c) 2017 Andy Somogyi (somogyie at indiana dot edu)
5 * Copyright (c) 2022-2024 T.J. Sego
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published
9 * by the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *
20 ******************************************************************************/
21
22#ifndef _MDCORE_INCLUDE_TF_LOCK_H_
23#define _MDCORE_INCLUDE_TF_LOCK_H_
24
25#include "tf_platform.h"
26
27#if (defined(_MSC_VER) && !defined(__GNUC__))
28#if defined(PTHREAD_LOCK)
29#include <pthread.h>
30#endif
31
32// #include <winnt.h>
33#include <intrin.h>
34#endif
35
36#if (defined(_MSC_VER) && !defined(__GNUC__))
37
38TF_ALWAYS_INLINE unsigned
39InterlockedExchangeAdd(int* Addend, int Value) {
40 return (unsigned)_InterlockedExchangeAdd((long*)Addend, (long)Value);
41}
42
43# define sync_val_compare_and_swap(x, y, z) (\
44 sizeof *(x) == sizeof(char) ? _InterlockedCompareExchange8 ((char*) (x), (char) (z), (char) (y)) : \
45 sizeof *(x) == sizeof(short) ? _InterlockedCompareExchange16((short*) (x), (short) (z), (short) (y)) : \
46 sizeof *(x) == sizeof(long) ? _InterlockedCompareExchange ((long*) (x), (long) (z), (long) (y)) : \
47 sizeof *(x) == sizeof(int64_t) ? InterlockedCompareExchange64 ((int64_t*)(x), (int64_t)(z), (int64_t)(y)) : \
48 (assert(!"Type error in sync_val_compare_and_swap"), 0))
49# define sync_fetch_and_add(a, b) _InterlockedExchangeAdd(a, b)
50# define sync_fetch_and_sub(a, b) _InterlockedExchangeAdd(a, -b)
51#else
52# define sync_val_compare_and_swap __sync_val_compare_and_swap
53# define sync_fetch_and_add(a, b) __sync_fetch_and_add(a, b)
54# define sync_fetch_and_sub(a, b) __sync_fetch_and_sub(a, b)
55#endif
56
57
58#ifdef PTHREAD_LOCK
59 #define lock_type pthread_spinlock_t
60 #define lock_init( l ) ( pthread_spin_init( l , PTHREAD_PROCESS_PRIVATE ) != 0 )
61 #define lock_destroy( l ) ( pthread_spin_destroy( l ) != 0 )
62 #define lock_lock( l ) ( pthread_spin_lock( l ) != 0 )
63 #define lock_trylock( l ) ( pthread_spin_lock( l ) != 0 )
64 #define lock_unlock( l ) ( pthread_spin_unlock( l ) != 0 )
65#else
66 #define lock_type volatile int
67 #define lock_init( l ) ( *l = 0 )
68 #define lock_destroy( l ) 0
69 TF_ALWAYS_INLINE int lock_lock ( volatile int *l ) {
70 while ( sync_val_compare_and_swap( l , 0 , 1 ) != 0 )
71 while( *l );
72 return 0;
73 }
74 #define lock_trylock( l ) ( ( *(l) ) ? 1 : sync_val_compare_and_swap( l , 0 , 1 ) )
75 #define lock_unlock( l ) ( sync_val_compare_and_swap( l , 1 , 0 ) != 1 )
76#endif
77
78#endif // _MDCORE_INCLUDE_TF_LOCK_H_