Ajla 0.1.4
[ajla.git] / addrlock.h
blob8523edced804280ff9d65225da057ba934d388d3
1 /*
2 * Copyright (C) 2024 Mikulas Patocka
4 * This file is part of Ajla.
6 * Ajla is free software: you can redistribute it and/or modify it under the
7 * terms of the GNU General Public License as published by the Free Software
8 * Foundation, either version 3 of the License, or (at your option) any later
9 * version.
11 * Ajla is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along with
16 * Ajla. If not, see <https://www.gnu.org/licenses/>.
19 #ifndef AJLA_ADDRLOCK_H
20 #define AJLA_ADDRLOCK_H
22 #include "thread.h"
24 #if defined(barrier_data_dependency) && \
25 defined(barrier_write_before_unlock_lock) && \
26 ((defined(POINTERS_ARE_ATOMIC) && \
27 (defined(POINTER_TAG) || \
28 defined(POINTER_IGNORE_BITS))) || \
29 defined(THREAD_NONE))
30 #define POINTER_FOLLOW_IS_LOCKLESS
31 #endif
34 * We need to determine refcount method here, so that we enable or disable
35 * DEPTH_REFCOUNT
37 #if !defined(THREAD_NONE) && defined(POINTERS_ARE_ATOMIC) && defined(INLINE_ASM_GCC_X86) && !defined(UNUSUAL_REFCOUNTS)
39 #if defined(INLINE_ASM_GCC_LABELS)
40 #define REFCOUNT_ASM_X86_LABELS
41 #elif defined(HAVE_C11_ATOMICS)
42 #define REFCOUNT_ATOMIC
43 #else
44 #define REFCOUNT_ASM_X86
45 #endif
47 #elif !defined(THREAD_NONE) && defined(HAVE_C11_ATOMICS) && !defined(UNUSUAL_REFCOUNTS)
49 #define REFCOUNT_ATOMIC
51 #elif !defined(THREAD_NONE) && defined(HAVE_SYNC_AND_FETCH) && !defined(UNUSUAL)
53 #define REFCOUNT_SYNC
55 #elif !defined(THREAD_NONE) && (defined(OS_WIN32) || defined(OS_CYGWIN)) && !defined(UNUSUAL_THREAD)
57 #define REFCOUNT_WIN32
59 #else
61 #define REFCOUNT_LOCK
63 #endif
65 #if defined(REFCOUNT_ATOMIC) || defined(REFCOUNT_WIN32) || defined(POINTERS_ARE_ATOMIC)
66 #define REFCOUNTS_ARE_ATOMIC
67 #endif
70 typedef enum {
71 DEPTH_THUNK,
72 #ifndef POINTER_FOLLOW_IS_LOCKLESS
73 DEPTH_POINTER,
74 #endif
75 #ifdef REFCOUNT_LOCK
76 DEPTH_REFCOUNT,
77 #endif
78 #ifdef USE_AMALLOC
79 DEPTH_ARENA,
80 #endif
81 #if (!defined(HAVE_PREAD) || !defined(HAVE_PWRITE)) && !defined(OS_OS2)
82 #define DO_LOCK_HANDLES
83 DEPTH_HANDLE,
84 #endif
85 DEPTH_AUX,
86 N_POINTER_DEPTHS
87 } addrlock_depth;
90 #if defined(THREAD_NONE) || defined(DEBUG_ALLOC_INSIDE_LOCKS)
91 #define POINTER_HASH_BITS 0
92 #else
93 #define POINTER_HASH_BITS 10
94 #endif
95 #define POINTER_HASH_SIZE (1 << POINTER_HASH_BITS)
97 #define mutex_padding_size (sizeof(mutex_t) <= 1 ? 1 : \
98 sizeof(mutex_t) <= 2 ? 2 : \
99 sizeof(mutex_t) <= 4 ? 4 : \
100 sizeof(mutex_t) <= 8 ? 8 : \
101 sizeof(mutex_t) <= 16 ? 16 : \
102 sizeof(mutex_t) <= 32 ? 32 : \
103 sizeof(mutex_t) <= 64 ? 64 : \
104 sizeof(mutex_t) <= 128 ? 128 : \
105 sizeof(mutex_t) <= 256 ? 256 : \
108 #define rwmutex_padding_size (sizeof(rwmutex_t) <= 1 ? 1 : \
109 sizeof(rwmutex_t) <= 2 ? 2 : \
110 sizeof(rwmutex_t) <= 4 ? 4 : \
111 sizeof(rwmutex_t) <= 8 ? 8 : \
112 sizeof(rwmutex_t) <= 16 ? 16 : \
113 sizeof(rwmutex_t) <= 32 ? 32 : \
114 sizeof(rwmutex_t) <= 64 ? 64 : \
115 sizeof(rwmutex_t) <= 128 ? 128 :\
116 sizeof(rwmutex_t) <= 256 ? 256 :\
120 void attr_fastcall address_lock(const void *, addrlock_depth);
121 void attr_fastcall address_unlock(const void *, addrlock_depth);
122 void attr_fastcall address_lock_two(const void *, const void *, addrlock_depth);
123 bool attr_fastcall address_trylock_second(const void *, const void *, addrlock_depth);
124 void attr_fastcall address_unlock_second(const void *, const void *, addrlock_depth);
125 mutex_t * attr_fastcall address_get_mutex(const void *, addrlock_depth);
127 void address_read_lock(const void *p);
128 void address_read_unlock(const void *p);
129 void address_write_lock(const void *p);
130 void address_write_unlock(const void *p);
132 #ifdef DEBUG_ALLOC_INSIDE_LOCKS
133 void address_lock_verify(void);
134 #else
135 static inline void address_lock_verify(void) { }
136 #endif
138 void address_lock_init(void);
139 void address_lock_done(void);
141 #endif